Skip to content
Snippets Groups Projects
Commit 3bcd85f2 authored by Daviti Gogshelidze's avatar Daviti Gogshelidze
Browse files

Add connectivity filter

parent 2073d19d
No related branches found
No related tags found
No related merge requests found
import {AfterViewInit, Component, ElementRef, OnDestroy, ViewChild, Input, ChangeDetectorRef} from "@angular/core";
import {select, Store} from "@ngrx/store";
import {fromEvent, Subscription, BehaviorSubject} from "rxjs";
import {catchError, take} from "rxjs/operators";
import {SAPI, SapiAtlasModel, SapiParcellationModel, SapiRegionModel} from "src/atlasComponents/sapi";
import {catchError} from "rxjs/operators";
import {
SAPI,
SapiAtlasModel,
SapiParcellationModel,
SapiRegionModel
} from "src/atlasComponents/sapi";
import { atlasAppearance, atlasSelection } from "src/state";
import {PARSE_TYPEDARRAY} from "src/atlasComponents/sapi/sapi.service";
import {SapiModalityModel, SapiParcellationFeatureMatrixModel} from "src/atlasComponents/sapi/type";
import { of } from "rxjs";
import {CustomLayer} from "src/state/atlasAppearance";
import {HttpClient} from "@angular/common/http";
import {environment} from "src/environments/environment";
@Component({
selector: 'sxplr-sapiviews-features-connectivity-browser',
......@@ -58,11 +65,6 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy {
private _defaultProfile
@Input() set defaultProfile(val: any) {
this._defaultProfile = val
this.selectedType = this.types.find(t => t.types.includes(val.type))?.name
this.pageNumber = 1
this.selectedDataset = this.fixDatasetFormat(val.selectedDataset)
if (val.matrix) this.setMatrixData(val.matrix)
this.numberOfDatasets = val.numberOfDatasets
}
get defaultProfile() {
......@@ -70,6 +72,14 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy {
}
public selectedType: any
public selectedTypeId: string
public selectedCohort: Cohort
public selectedSubjectIndex: number
public selectedSubjectDatasetIndex: number
public cohorts: Cohort[]
public selectedView: 'subject' | 'average' | null
public averageDisabled: boolean = true
public subjectsDisabled: boolean = true
@Input()
set region(val) {
......@@ -97,10 +107,8 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy {
public defaultColorMap: Map<string, Map<number, { red: number, green: number, blue: number }>>
public matrixString: string
public fetching: boolean
public numberOfDatasets: number
public connectivityLayerId = 'connectivity-colormap-id'
private setCustomLayerOnLoad = false
public pageNumber: number
private customLayerEnabled: boolean
public logDisabled: boolean = true
......@@ -113,6 +121,7 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy {
private store$: Store,
private sapi: SAPI,
private changeDetectionRef: ChangeDetectorRef,
private httpClient: HttpClient
) {}
public ngAfterViewInit(): void {
......@@ -182,35 +191,56 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy {
selectType(typeName) {
this.selectedType = typeName
this.pageNumber = 1
this.loadDataset()
this.selectedTypeId = this.types.find(t => t.name === typeName).types[0]
this.selectedCohort = null
this.cohorts = null
this.fetchCohorts()
}
datasetSliderChanged(pageNumber) {
this.pageNumber = pageNumber
this.loadDataset()
getCohortsReq() {
const { SIIBRA_API_ENDPOINTS } = environment
const endp = SIIBRA_API_ENDPOINTS.split(',')[0]
return this.sapi.http.get(
`${endp}/atlases/${encodeURIComponent(this.atlas['@id'])}/parcellations/${encodeURIComponent(this.parcellation['@id'])}/features?type=${this.selectedTypeId}&group=cohort_subject`,
)
}
fetchCohorts() {
this.subscriptions.push(
this.getCohortsReq().subscribe((c: Cohort[]) => {
this.cohorts = c
})
)
}
selectCohort(cohort: Cohort) {
this.selectedCohort = cohort
this.averageDisabled = !this.selectedCohort.subjects.find(s => s.subject === 'average')
this.subjectsDisabled = !this.selectedCohort.subjects.find(s => s.subject !== 'average')
this.selectedView = !this.averageDisabled? 'average' : 'subject'
this.selectedSubjectIndex = 0
this.selectedSubjectDatasetIndex = 0
this.loadSubjectConnectivity()
}
subjectSliderChanged(index) {
this.selectedSubjectIndex = this.selectedCohort.subjects.findIndex((s, i) => i === index)
this.selectedSubjectDatasetIndex = 0
this.loadSubjectConnectivity()
}
subjectDatasetSliderChanged(index) {
this.selectedSubjectDatasetIndex = index
this.loadSubjectConnectivity()
}
loadDataset() {
loadSubjectConnectivity() {
this.fetching = true
const type = this.types.find(t => t.name === this.selectedType).types[0]
return this.sapi.getParcellation(this.atlas["@id"], this.parcellation["@id"])
.getFeatures({type, page: this.pageNumber, size: 1},)
.pipe(
take(1),
catchError(() => {
this.fetching = false
return of(null)
})
).subscribe((res: any) => {
if (res && res.items) {
if (res.total !== this.numberOfDatasets) {
this.numberOfDatasets = res.total
}
this.selectedDataset = this.fixDatasetFormat(res.items[0])
this.fetchConnectivity()
}
})
this.fetchConnectivity(this.selectedCohort.subjects[this.selectedSubjectIndex].datasets[this.selectedSubjectDatasetIndex])
}
// ToDo this temporary fix is for the bug existing on siibra api https://github.com/FZJ-INM1-BDA/siibra-api/issues/100
......@@ -219,13 +249,14 @@ export class ConnectivityBrowserComponent implements AfterViewInit, OnDestroy {
...JSON.parse(ds.name.substring(ds.name.indexOf('{')).replace(/'/g, '"'))
}) : ds
fetchConnectivity() {
this.sapi.getParcellation(this.atlas["@id"], this.parcellation["@id"]).getFeatureInstance(this.selectedDataset['@id'])
fetchConnectivity(datasetId=null) {
this.sapi.getParcellation(this.atlas["@id"], this.parcellation["@id"]).getFeatureInstance(datasetId || this.selectedDataset['@id'])
.pipe(catchError(() => {
this.fetching = false
return of(null)
}))
.subscribe(ds=> {
this.selectedDataset = this.fixDatasetFormat(ds)
this.setMatrixData(ds)
this.fetching = false
})
......@@ -336,3 +367,10 @@ export type ConnectedArea = {
numberOfConnections: number
}
export type Cohort = {
cohort: string
subjects: {
subject: string
datasets: string[]
}[]
}
<div class="w-100 h-100 d-block d-flex flex-column sxplr-pb-2">
<div>
<div *ngIf="types && types.length && selectedType" class="flex-grow-0 flex-shrink-0 d-flex flex-row flex-nowrap">
<mat-form-field class="flex-grow-1 flex-shrink-1 w-0">
<div *ngIf="types && types.length"
class="flex-grow-0 flex-shrink-0 d-flex flex-row flex-nowrap d-flex flex-column">
<mat-form-field class="flex-grow-1 flex-shrink-1 w-100">
<mat-label>
Modality
</mat-label>
......@@ -17,22 +18,65 @@
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field *ngIf="selectedType" class="flex-grow-1 flex-shrink-1 w-100">
<mat-label>
Cohort
</mat-label>
<mat-select
[value]="selectedCohort"
(selectionChange)="selectCohort($event.value)">
<mat-option
*ngFor="let cohort of cohorts"
[value]="cohort">
{{ cohort.cohort }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div *ngIf="selectedDataset" class="flex-grow-0 flex-shrink-0 d-flex flex-nowrap align-items-center">
<div class="flex-grow-1 flex-shrink-1 w-0">
<mat-radio-group *ngIf="selectedCohort && selectedCohort.subjects" [(ngModel)]="selectedView">
<mat-radio-button value="average" class="m-2" [disabled]="averageDisabled" color="primary">
Average
</mat-radio-button>
<mat-radio-button value="subject" class="m-2" [disabled]="subjectsDisabled" color="primary">
Subject
</mat-radio-button>
</mat-radio-group>
<div *ngIf="selectedView !== 'average' && selectedCohort && selectedCohort.subjects"
class="flex-grow-0 flex-shrink-0 d-flex flex-column">
<div class="flex-grow-1 flex-shrink-1 w-100">
<mat-label>
Dataset
Subject
</mat-label>
<mat-slider [min]="1"
[max]="numberOfDatasets"
(change)="datasetSliderChanged($event.value)"
[value]="pageNumber"
<mat-slider [min]="0"
[max]="selectedCohort.subjects.length-1"
(change)="subjectSliderChanged($event.value)"
[value]="selectedSubjectIndex"
thumbLabel
step="1"
class="w-100">
</mat-slider>
</div>
<div *ngIf="selectedSubjectIndex >= 0 && selectedCohort.subjects[selectedSubjectIndex].datasets.length > 1"
class="flex-grow-0 flex-shrink-0 d-flex flex-nowrap align-items-center">
<div class="flex-grow-1 flex-shrink-1 w-100">
<mat-label>
Datasets
</mat-label>
<mat-slider [min]="0"
[max]="selectedCohort.subjects[selectedSubjectIndex].datasets.length-1"
(change)="subjectDatasetSliderChanged($event.value)"
[value]="selectedSubjectDatasetIndex"
thumbLabel
step="1"
class="w-100">
</mat-slider>
</div>
</div>
</div>
</div>
......@@ -41,7 +85,9 @@
<mat-spinner *ngIf="fetching"></mat-spinner>
</div>
<div class="d-flex align-items-center" *ngIf="regionName && !fetching">
<div *ngIf="regionName && !fetching"
[style.visibility]="selectedCohort && (selectedSubjectDatasetIndex >= 0 || !averageDisabled)? 'visible' : 'hidden'"
class="d-flex align-items-center">
<mat-checkbox class="mr-2"
[checked]="logChecked"
(change)="changeLog($event.checked)"
......@@ -55,6 +101,7 @@
<hbp-connectivity-matrix-row
#connectivityComponent
[style.visibility]="selectedCohort && (selectedSubjectDatasetIndex >= 0 || !averageDisabled)? 'visible' : 'hidden'"
*ngIf="regionName && !fetching && !noConnectivityForRegion"
[region]="regionName + (regionHemisphere? ' - ' + regionHemisphere : '')"
[connections]="connectionsString"
......
......@@ -4,10 +4,12 @@ import { SAPI } from "src/atlasComponents/sapi";
import {ConnectivityBrowserComponent} from "src/atlasComponents/sapiViews/features/connectivity/connectivityBrowser/connectivityBrowser.component";
import {HasConnectivity} from "src/atlasComponents/sapiViews/features/connectivity/hasConnectivity.directive";
import {AngularMaterialModule} from "src/sharedModules";
import {FormsModule} from "@angular/forms";
@NgModule({
imports: [
CommonModule,
FormsModule,
AngularMaterialModule
],
declarations: [
......
......@@ -31,6 +31,7 @@ import { ClipboardModule } from '@angular/cdk/clipboard'
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import {MatProgressBarModule} from "@angular/material/progress-bar";
import {MatProgressSpinnerModule} from "@angular/material/progress-spinner";
import {MatRadioModule} from "@angular/material/radio";
const defaultDialogOption: MatDialogConfig = new MatDialogConfig()
......@@ -67,6 +68,7 @@ const defaultDialogOption: MatDialogConfig = new MatDialogConfig()
ClipboardModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule
],
exports: [
MatButtonModule,
......@@ -98,6 +100,7 @@ const defaultDialogOption: MatDialogConfig = new MatDialogConfig()
ClipboardModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule
],
providers: [{
provide: MAT_DIALOG_DEFAULT_OPTIONS,
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment