Skip to content

Commit 9349e91

Browse files
authored
Merge pull request #54 from omics-datascience/feature/datasets_experiments
Feature/datasets experiments
2 parents 9176766 + 3cae0e8 commit 9349e91

File tree

14 files changed

+213
-32
lines changed

14 files changed

+213
-32
lines changed

src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/BiomarkerTrainedModelsTable.tsx

+11
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { TrainedModelStateLabel } from '../labels/TrainedModelStateLabel'
1212
import ky from 'ky'
1313
import { StopExperimentButton } from '../../pipeline/all-experiments-view/StopExperimentButton'
1414
import { DeleteExperimentButton } from '../../pipeline/all-experiments-view/DeleteExperimentButton'
15+
import { TableCellSources } from '../../common/TableCellSources'
1516

1617
declare const urlBiomarkerTrainedModels: string
1718
declare const urlStopTrainedModel: string
@@ -213,6 +214,7 @@ export const BiomarkerTrainedModelsTable = (props: BiomarkerTrainedModelsPanelPr
213214
{ name: 'Date', serverCodeToSort: 'created' },
214215
{ name: 'Metric', serverCodeToSort: 'fitness_metric' },
215216
{ name: 'Best CV metric', serverCodeToSort: 'best_fitness_value' },
217+
{ name: 'Datasets' },
216218
...actionColumn
217219
]}
218220
defaultSortProp={{ sortField: 'created', sortOrderAscendant: false }}
@@ -271,6 +273,15 @@ export const BiomarkerTrainedModelsTable = (props: BiomarkerTrainedModelsPanelPr
271273
<TableCellWithTitle value={formatDateLocale(trainedModel.created as string, 'L')} />
272274
<Table.Cell>{trainedModel.fitness_metric ?? '-'}</Table.Cell>
273275
<Table.Cell>{trainedModel.best_fitness_value ? trainedModel.best_fitness_value.toFixed(4) : '-'}</Table.Cell>
276+
<Table.Cell>
277+
<TableCellSources
278+
clinical_source={trainedModel.clinical_source}
279+
methylation_source={trainedModel.mrna_source}
280+
mrna_source={trainedModel.mirna_source}
281+
cna_source={trainedModel.cna_source}
282+
mirna_source={trainedModel.methylation_source}
283+
/>
284+
</Table.Cell>
274285

275286
{/* Actions column */}
276287
{props.allowFullManagement &&

src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/inference/InferenceExperimentsTable.tsx

+11
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import ky from 'ky'
1010
import { Nullable } from '../../../../utils/interfaces'
1111
import { StopExperimentButton } from '../../../pipeline/all-experiments-view/StopExperimentButton'
1212
import { DeleteExperimentButton } from '../../../pipeline/all-experiments-view/DeleteExperimentButton'
13+
import { TableCellSources } from '../../../common/TableCellSources'
1314

1415
declare const urlBiomarkerInferenceExperiments: string
1516
declare const urlStopInferenceExperiment: string
@@ -171,6 +172,7 @@ export const InferenceExperimentsTable = (props: InferenceExperimentsTableProps)
171172
{ name: 'State', serverCodeToSort: 'state', textAlign: 'center' },
172173
{ name: 'Model', serverCodeToSort: 'model', width: 1 },
173174
{ name: 'Date', serverCodeToSort: 'created' },
175+
{ name: 'Datasets' },
174176
{ name: 'Actions' }
175177
]}
176178
queryParams={{ biomarker_pk: props.selectedBiomarker.id }}
@@ -201,6 +203,15 @@ export const InferenceExperimentsTable = (props: InferenceExperimentsTableProps)
201203
</Table.Cell>
202204
<Table.Cell><FitnessFunctionLabel fitnessFunction={inferenceExperiment.model} /></Table.Cell>
203205
<TableCellWithTitle value={formatDateLocale(inferenceExperiment.created as string, 'L')} />
206+
<Table.Cell>
207+
<TableCellSources
208+
clinical_source={inferenceExperiment.clinical_source}
209+
methylation_source={inferenceExperiment.mrna_source}
210+
mrna_source={inferenceExperiment.mirna_source}
211+
cna_source={inferenceExperiment.cna_source}
212+
mirna_source={inferenceExperiment.methylation_source}
213+
/>
214+
</Table.Cell>
204215
<Table.Cell width={1}>
205216
{inferenceExperiment.state === BiomarkerState.COMPLETED &&
206217
<Icon

src/frontend/static/frontend/src/components/biomarkers/biomarker-details-modal/stat-validations/StatisticalValidationsTable.tsx

+11
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import ky from 'ky'
1010
import { StopExperimentButton } from '../../../pipeline/all-experiments-view/StopExperimentButton'
1111
import { Nullable } from '../../../../utils/interfaces'
1212
import { DeleteExperimentButton } from '../../../pipeline/all-experiments-view/DeleteExperimentButton'
13+
import { TableCellSources } from '../../../common/TableCellSources'
1314

1415
declare const urlBiomarkerStatisticalValidations: string
1516
declare const urlStopStatisticalValidation: string
@@ -173,6 +174,7 @@ export const StatisticalValidationsTable = (props: StatisticalValidationsTablePr
173174
{ name: 'State', serverCodeToSort: 'state', textAlign: 'center' },
174175
{ name: 'Model', textAlign: 'center', width: 2 },
175176
{ name: 'Date', serverCodeToSort: 'created' },
177+
{ name: 'Datasets' },
176178
{ name: 'Actions' }
177179
]}
178180
queryParams={{ biomarker_pk: props.selectedBiomarker.id }}
@@ -205,6 +207,15 @@ export const StatisticalValidationsTable = (props: StatisticalValidationsTablePr
205207
<FitnessFunctionLabel fitnessFunction={statisticalValidation.fitness_function} />
206208
</Table.Cell>
207209
<TableCellWithTitle value={formatDateLocale(statisticalValidation.created as string, 'L')} />
210+
<Table.Cell>
211+
<TableCellSources
212+
clinical_source={statisticalValidation.clinical_source}
213+
methylation_source={statisticalValidation.mrna_source}
214+
mrna_source={statisticalValidation.mirna_source}
215+
cna_source={statisticalValidation.cna_source}
216+
mirna_source={statisticalValidation.methylation_source}
217+
/>
218+
</Table.Cell>
208219
<Table.Cell width={1}>
209220
{statisticalValidation.state === BiomarkerState.COMPLETED &&
210221
<Icon

src/frontend/static/frontend/src/components/biomarkers/labels/MoleculeTypeLabel.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react'
22
import { Label, SemanticCOLORS } from 'semantic-ui-react'
3-
import { MoleculeType } from '../../../utils/interfaces'
3+
import { GenesColors, MoleculeType } from '../../../utils/interfaces'
44

55
/** MoleculeTypeLabel props. */
66
interface MoleculeTypeLabelProps {
@@ -23,19 +23,19 @@ export const MoleculeTypeLabel = (props: MoleculeTypeLabelProps) => {
2323

2424
switch (props.moleculeType) {
2525
case MoleculeType.MRNA:
26-
color = 'blue'
26+
color = GenesColors.MRNA
2727
description = 'mRNA'
2828
break
2929
case MoleculeType.MIRNA:
30-
color = 'orange'
30+
color = GenesColors.MIRNA
3131
description = 'miRNA'
3232
break
3333
case MoleculeType.CNA:
34-
color = 'yellow'
34+
color = GenesColors.CNA
3535
description = 'CNA'
3636
break
3737
case MoleculeType.METHYLATION:
38-
color = 'olive'
38+
color = GenesColors.METHYLATION
3939
description = 'Methylation'
4040
break
4141
default:

src/frontend/static/frontend/src/components/biomarkers/types.ts

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DjangoTag } from '../../utils/django_interfaces'
1+
import { DjangoExperimentSource, DjangoTag } from '../../utils/django_interfaces'
22
import { MoleculeType, Nullable, Source } from '../../utils/interfaces'
33
import { KaplanMeierData } from '../pipeline/experiment-result/gene-gem-details/survival-analysis/KaplanMeierUtils'
44

@@ -407,6 +407,11 @@ interface TrainedModelForTable {
407407
cv_folds_modified: boolean,
408408
created: string,
409409
can_be_deleted: boolean,
410+
clinical_source: DjangoExperimentSource,
411+
methylation_source: Nullable<DjangoExperimentSource>,
412+
mrna_source: Nullable<DjangoExperimentSource>,
413+
cna_source: Nullable<DjangoExperimentSource>,
414+
mirna_source: Nullable<DjangoExperimentSource>,
410415
fitness_metric: Nullable<string>,
411416
best_fitness_value: Nullable<number>
412417
}
@@ -437,6 +442,11 @@ interface BasicStatisticalValidation {
437442
interface StatisticalValidationForTable extends BasicStatisticalValidation {
438443
fitness_function: FitnessFunction,
439444
trained_model: Nullable<number>,
445+
clinical_source: Nullable<DjangoExperimentSource>,
446+
methylation_source: Nullable<DjangoExperimentSource>,
447+
mrna_source: Nullable<DjangoExperimentSource>,
448+
cna_source: Nullable<DjangoExperimentSource>,
449+
mirna_source: Nullable<DjangoExperimentSource>,
440450
}
441451

442452
/** A statistical validation of a Biomarker. */
@@ -467,6 +477,11 @@ interface InferenceExperimentForTable {
467477
trained_model: Nullable<number>,
468478
clinical_source_id: Nullable<number>
469479
created: string
480+
clinical_source: Nullable<DjangoExperimentSource>,
481+
methylation_source: Nullable<DjangoExperimentSource>,
482+
mrna_source: Nullable<DjangoExperimentSource>,
483+
cna_source: Nullable<DjangoExperimentSource>,
484+
mirna_source: Nullable<DjangoExperimentSource>,
470485
}
471486

472487
/** Django MoleculeWithCoefficient model. */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import React from 'react'
2+
import { SourcePopup } from '../pipeline/all-experiments-view/SourcePopup'
3+
import { DjangoExperimentSource } from '../../utils/django_interfaces'
4+
import { GenesColors, Nullable } from '../../utils/interfaces'
5+
6+
/**
7+
* Component to show sourcePopups if files provides
8+
* @returns component
9+
*/
10+
interface Props {
11+
clinical_source: Nullable<DjangoExperimentSource>,
12+
methylation_source: Nullable<DjangoExperimentSource>,
13+
mrna_source: Nullable<DjangoExperimentSource>,
14+
cna_source: Nullable<DjangoExperimentSource>,
15+
mirna_source: Nullable<DjangoExperimentSource>,
16+
}
17+
18+
export const TableCellSources = (props: Props) => {
19+
return (
20+
<>
21+
{
22+
/* Download clinical file */
23+
props.clinical_source &&
24+
<SourcePopup
25+
source={props.clinical_source}
26+
iconName='file'
27+
iconColor={GenesColors.CLINICAL}
28+
downloadButtonTitle='Download source clinical file'
29+
/>
30+
}
31+
{
32+
/* Download mRna file */
33+
props.mrna_source &&
34+
<SourcePopup
35+
source={props.mrna_source}
36+
iconName='file alternate'
37+
iconColor={GenesColors.MRNA}
38+
downloadButtonTitle='Download source mRna file'
39+
/>
40+
}
41+
{
42+
/* Download mirna file */
43+
props.mirna_source &&
44+
<SourcePopup
45+
source={props.mirna_source}
46+
iconName='file alternate'
47+
iconColor={GenesColors.MIRNA}
48+
downloadButtonTitle='Download source mirna file'
49+
/>
50+
}
51+
{
52+
/* Download cna file */
53+
props.cna_source &&
54+
<SourcePopup
55+
source={props.cna_source}
56+
iconName='file alternate'
57+
iconColor={GenesColors.CNA}
58+
downloadButtonTitle='Download source cna file'
59+
/>
60+
}
61+
{
62+
/* Download methylation file */
63+
props.methylation_source &&
64+
<SourcePopup
65+
source={props.methylation_source}
66+
iconName='file alternate'
67+
iconColor={GenesColors.METHYLATION}
68+
downloadButtonTitle='Download source methylation file'
69+
/>
70+
}
71+
</>
72+
)
73+
}

src/frontend/static/frontend/src/components/files-manager/FilesManager.tsx

+44-16
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ declare const urlUserInstitutions: string
2929
declare const urlChunkUpload: string
3030
declare const urlChunkUploadComplete: string
3131
declare const downloadFileURL: string
32+
declare const downloadFileHeaders: string
3233

3334
/**
3435
* New File Form fields
@@ -612,21 +613,49 @@ class FilesManager extends React.Component<{}, FilesManagerState> {
612613
* @param fileToEdit Selected file to edit
613614
*/
614615
editFile = (fileToEdit: DjangoUserFile) => {
615-
this.setState({
616-
newFile: {
617-
id: fileToEdit.id,
618-
newFileName: fileToEdit.name,
619-
newFileNameUser: fileToEdit.name,
620-
newFileType: fileToEdit.file_type,
621-
newFileDescription: fileToEdit.description ?? '',
622-
newTag: fileToEdit.tag ? fileToEdit.tag.id : null,
623-
isCpGSiteId: fileToEdit.is_cpg_site_id,
624-
platform: fileToEdit.platform ? fileToEdit.platform : DjangoMethylationPlatform.PLATFORM_450,
625-
// We only need the IDs
626-
institutions: fileToEdit.institutions.map((institution) => institution.id),
627-
survivalColumns: fileToEdit.survival_columns ?? []
628-
}
629-
})
616+
if (fileToEdit.file_type === FileType.CLINICAL) {
617+
ky.get(`${downloadFileHeaders}${fileToEdit.id}`, { signal: this.abortController.signal }).then((response) => {
618+
response.json().then((fileHeaders: string[]) => {
619+
// Recieve file separates by , to get array of headers
620+
const survivalTuplesPossiblesValues = fileHeaders
621+
this.setState({
622+
survivalTuplesPossiblesValues,
623+
newFile: {
624+
id: fileToEdit.id,
625+
newFileName: fileToEdit.name,
626+
newFileNameUser: fileToEdit.name,
627+
newFileType: fileToEdit.file_type,
628+
newFileDescription: fileToEdit.description ?? '',
629+
newTag: fileToEdit.tag ? fileToEdit.tag.id : null,
630+
isCpGSiteId: fileToEdit.is_cpg_site_id,
631+
platform: fileToEdit.platform ? fileToEdit.platform : DjangoMethylationPlatform.PLATFORM_450,
632+
institutions: fileToEdit.institutions.map((institution) => institution.id),
633+
survivalColumns: fileToEdit.survival_columns ?? []
634+
}
635+
})
636+
}).catch((err) => {
637+
console.log('Error parsing JSON ->', err)
638+
})
639+
}).catch((err) => {
640+
console.log('Error getting file content ->', err)
641+
})
642+
} else {
643+
this.setState({
644+
survivalTuplesPossiblesValues: [],
645+
newFile: {
646+
id: fileToEdit.id,
647+
newFileName: fileToEdit.name,
648+
newFileNameUser: fileToEdit.name,
649+
newFileType: fileToEdit.file_type,
650+
newFileDescription: fileToEdit.description ?? '',
651+
newTag: fileToEdit.tag ? fileToEdit.tag.id : null,
652+
isCpGSiteId: fileToEdit.is_cpg_site_id,
653+
platform: fileToEdit.platform ? fileToEdit.platform : DjangoMethylationPlatform.PLATFORM_450,
654+
institutions: fileToEdit.institutions.map((institution) => institution.id),
655+
survivalColumns: fileToEdit.survival_columns ?? []
656+
}
657+
})
658+
}
630659
}
631660

632661
/**
@@ -726,7 +755,6 @@ class FilesManager extends React.Component<{}, FilesManagerState> {
726755
const fileDeletionConfirmModal = this.getFileDeletionConfirmModals()
727756

728757
const fileTypeOptions = getFileTypeSelectOptions(false)
729-
730758
const tagOptions: DropdownItemProps[] = this.state.tags.map((tag) => {
731759
const id = tag.id as number
732760
return { key: id, value: id, text: tag.name }

src/frontend/static/frontend/src/components/pipeline/all-experiments-view/AllExperimentsView.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react'
22
import { Table, TableCell, Icon, DropdownItemProps } from 'semantic-ui-react'
3-
import { AllExperimentsTableControl, Nullable } from '../../../utils/interfaces'
3+
import { AllExperimentsTableControl, GenesColors, Nullable } from '../../../utils/interfaces'
44
import { DjangoExperiment, DjangoTag, ExperimentState, ExperimentType, CorrelationMethod } from '../../../utils/django_interfaces'
55
import { getExperimentTypeSelectOptions, getCorrelationMethodSelectOptions, formatDateLocale, getExperimentTypeObj, getExperimentCorrelationMethodInfo, getExperimentStateObj } from '../../../utils/util_functions'
66
import { PaginatedTable, PaginationCustomFilter } from '../../common/PaginatedTable'
@@ -192,15 +192,15 @@ export class AllExperimentsView extends React.Component<AllExperimentsViewProps,
192192
<SourcePopup
193193
source={experiment.mRNA_source}
194194
iconName='file'
195-
iconColor='blue'
195+
iconColor={GenesColors.MRNA}
196196
downloadButtonTitle='Download source mRNA file'
197197
/>
198198

199199
{/* Download GEM file */}
200200
<SourcePopup
201201
source={experiment.gem_source}
202202
iconName='file alternate'
203-
iconColor='teal'
203+
iconColor={GenesColors.MIRNA}
204204
downloadButtonTitle={`Download ${getExperimentTypeObj(experiment.type, 'ExperimentType').description} source file`}
205205
/>
206206
</TableCell>

src/frontend/static/frontend/src/components/survival/SurvivalTuplesForm.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ export const SurvivalTuplesForm = (props: SurvivalTuplesFormProps) => {
8383
{props.survivalColumns?.map((survivalColumn, idx) => {
8484
const checkedHandleSurvivalFormChanges = checkedValidityCallback(
8585
(name, value) => {
86-
console.log(name, value)
8786
const callback = props.handleSurvivalFormDatasetChanges
8887
return callback(idx, name, value)
8988
}

src/frontend/static/frontend/src/utils/interfaces.ts

+17-5
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,13 @@ interface GeneralTableControlWithoutSorting {
122122
// TODO: after big refactoring using only PaginatedTable.tsx, check if totalRowCount is optional
123123
totalRowCount?: number,
124124
// TODO: after big refactoring using only PaginatedTable.tsx, check if filters is optional
125-
filters: { [key: string]: {
126-
value: any,
127-
/** Indicates if 0 as filter value is accepted */
128-
allowZero?: boolean
129-
} },
125+
filters: {
126+
[key: string]: {
127+
value: any,
128+
/** Indicates if 0 as filter value is accepted */
129+
allowZero?: boolean
130+
}
131+
},
130132
}
131133

132134
/**
@@ -308,7 +310,17 @@ type OkResponse = {
308310
ok: boolean
309311
}
310312

313+
/** Types for genes colors */
314+
enum GenesColors {
315+
MRNA = 'blue',
316+
MIRNA = 'orange',
317+
CNA = 'yellow',
318+
METHYLATION = 'olive',
319+
CLINICAL = 'teal'
320+
}
321+
311322
export {
323+
GenesColors,
312324
CustomAlertTypes,
313325
CustomAlert,
314326
Nullable,

0 commit comments

Comments
 (0)