From 7bdf4b8e855d39a8c5aa623ebfe4c96ba8ce58c4 Mon Sep 17 00:00:00 2001 From: Xiao Gui <xgui3783@gmail.com> Date: Tue, 14 Mar 2023 11:05:51 +0100 Subject: [PATCH] chore: rm unused module --- tmpFeatures/entry/entry.component.ts | 181 ----------------- tmpFeatures/entry/entry.style.css | 0 tmpFeatures/entry/entry.template.html | 22 --- .../entryListItem/entryListItem.component.ts | 45 ----- .../entryListItem/entryListItem.style.css | 5 - .../entryListItem/entryListItem.template.html | 17 -- .../entryListItem/entryListitem.stories.ts | 88 --------- tmpFeatures/featureBadgeColor.pipe.ts | 19 -- tmpFeatures/featureBadgeFlag.pipe.ts | 14 -- tmpFeatures/featureBadgeName.pipe.ts | 19 -- .../ieeg/ieegDataset/ieegDataset.component.ts | 113 ----------- .../ieeg/ieegDataset/ieegDataset.stories.ts | 113 ----------- .../ieeg/ieegDataset/ieegDataset.style.css | 4 - .../ieegDataset/ieegDataset.template.html | 112 ----------- tmpFeatures/ieeg/inRoi.pipe.ts | 19 -- tmpFeatures/ieeg/index.ts | 2 - tmpFeatures/ieeg/module.ts | 33 ---- tmpFeatures/index.ts | 7 - tmpFeatures/module.ts | 53 ----- tmpFeatures/orderFilterFeatureList.pipe.ts | 37 ---- .../autoradiography/autoradiograph.stories.ts | 146 -------------- .../autoradiography.component.ts | 82 -------- .../autoradiography/autoradiography.style.css | 0 .../autoradiography.template.html | 0 tmpFeatures/receptors/base.ts | 100 ---------- .../receptors/entry/entry.component.ts | 43 ---- tmpFeatures/receptors/entry/entry.stories.ts | 127 ------------ tmpFeatures/receptors/entry/entry.style.css | 4 - .../receptors/entry/entry.template.html | 80 -------- .../fingerprint/fingerprint.component.ts | 133 ------------- .../fingerprint/fingerprint.stories.ts | 128 ------------ .../fingerprint/fingerprint.style.css | 0 .../fingerprint/fingerprint.template.html | 3 - tmpFeatures/receptors/index.ts | 4 - tmpFeatures/receptors/module.ts | 40 ---- .../receptors/profile/profile.component.ts | 91 --------- .../receptors/profile/profile.stories.ts | 155 --------------- .../receptors/profile/profile.style.css | 0 .../receptors/profile/profile.template.html | 3 - tmpFeatures/voi/index.ts | 2 - tmpFeatures/voi/module.ts | 19 -- tmpFeatures/voi/voiQuery.directive.ts | 187 ------------------ 42 files changed, 2250 deletions(-) delete mode 100644 tmpFeatures/entry/entry.component.ts delete mode 100644 tmpFeatures/entry/entry.style.css delete mode 100644 tmpFeatures/entry/entry.template.html delete mode 100644 tmpFeatures/entryListItem/entryListItem.component.ts delete mode 100644 tmpFeatures/entryListItem/entryListItem.style.css delete mode 100644 tmpFeatures/entryListItem/entryListItem.template.html delete mode 100644 tmpFeatures/entryListItem/entryListitem.stories.ts delete mode 100644 tmpFeatures/featureBadgeColor.pipe.ts delete mode 100644 tmpFeatures/featureBadgeFlag.pipe.ts delete mode 100644 tmpFeatures/featureBadgeName.pipe.ts delete mode 100644 tmpFeatures/ieeg/ieegDataset/ieegDataset.component.ts delete mode 100644 tmpFeatures/ieeg/ieegDataset/ieegDataset.stories.ts delete mode 100644 tmpFeatures/ieeg/ieegDataset/ieegDataset.style.css delete mode 100644 tmpFeatures/ieeg/ieegDataset/ieegDataset.template.html delete mode 100644 tmpFeatures/ieeg/inRoi.pipe.ts delete mode 100644 tmpFeatures/ieeg/index.ts delete mode 100644 tmpFeatures/ieeg/module.ts delete mode 100644 tmpFeatures/index.ts delete mode 100644 tmpFeatures/module.ts delete mode 100644 tmpFeatures/orderFilterFeatureList.pipe.ts delete mode 100644 tmpFeatures/receptors/autoradiography/autoradiograph.stories.ts delete mode 100644 tmpFeatures/receptors/autoradiography/autoradiography.component.ts delete mode 100644 tmpFeatures/receptors/autoradiography/autoradiography.style.css delete mode 100644 tmpFeatures/receptors/autoradiography/autoradiography.template.html delete mode 100644 tmpFeatures/receptors/base.ts delete mode 100644 tmpFeatures/receptors/entry/entry.component.ts delete mode 100644 tmpFeatures/receptors/entry/entry.stories.ts delete mode 100644 tmpFeatures/receptors/entry/entry.style.css delete mode 100644 tmpFeatures/receptors/entry/entry.template.html delete mode 100644 tmpFeatures/receptors/fingerprint/fingerprint.component.ts delete mode 100644 tmpFeatures/receptors/fingerprint/fingerprint.stories.ts delete mode 100644 tmpFeatures/receptors/fingerprint/fingerprint.style.css delete mode 100644 tmpFeatures/receptors/fingerprint/fingerprint.template.html delete mode 100644 tmpFeatures/receptors/index.ts delete mode 100644 tmpFeatures/receptors/module.ts delete mode 100644 tmpFeatures/receptors/profile/profile.component.ts delete mode 100644 tmpFeatures/receptors/profile/profile.stories.ts delete mode 100644 tmpFeatures/receptors/profile/profile.style.css delete mode 100644 tmpFeatures/receptors/profile/profile.template.html delete mode 100644 tmpFeatures/voi/index.ts delete mode 100644 tmpFeatures/voi/module.ts delete mode 100644 tmpFeatures/voi/voiQuery.directive.ts diff --git a/tmpFeatures/entry/entry.component.ts b/tmpFeatures/entry/entry.component.ts deleted file mode 100644 index 691af83bd..000000000 --- a/tmpFeatures/entry/entry.component.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { Component, Input, OnDestroy } from "@angular/core"; -import { Store } from "@ngrx/store"; -import { TNgAnnotationPoint } from "src/atlasComponents/annotations"; -import { SapiFeatureModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel, CLEANED_IEEG_DATASET_TYPE } from "src/atlasComponents/sapi"; -import { IeegOnFocusEvent, ContactPoint, Electrode, Session, IeegOnDefocusEvent } from "../ieeg"; -import { atlasSelection, annotation } from "src/state" - -@Component({ - selector: 'sxplr-sapiviews-features-entry', - templateUrl: './entry.template.html', - styleUrls: [ - './entry.style.css' - ] -}) - -export class FeatureEntryCmp implements OnDestroy{ - - /** - * in future, hopefully feature detail can be queried with just id, - * and atlas/space/parcellation/region are no longer necessary - */ - @Input('sxplr-sapiviews-features-entry-atlas') - atlas: SapiFeatureModel - - @Input('sxplr-sapiviews-features-entry-space') - space: SapiSpaceModel - - @Input('sxplr-sapiviews-features-entry-parcellation') - parcellation: SapiParcellationModel - - @Input('sxplr-sapiviews-features-entry-region') - region: SapiRegionModel - - @Input('sxplr-sapiviews-features-entry-feature') - feature: SapiFeatureModel - - featureType = { - receptor: "siibra/features/receptor", - ieeg: CLEANED_IEEG_DATASET_TYPE - } - - private addedAnnotations: annotation.UnionAnnotation[] = [] - - ieegOnFocus(ev: IeegOnFocusEvent){ - if (ev.contactPoint) { - /** - * navigate to the point - */ - this.store.dispatch( - atlasSelection.actions.navigateTo({ - navigation: { - position: ev.contactPoint.point.coordinates.map(v => v.value * 1e6) - }, - animation: true - }) - ) - return - } - if (ev.session) { - /** - * - */ - const allInRoiPoints: TNgAnnotationPoint[] = this.getPointsFromSession(ev.session, true) - const allNonInRoiPoints: TNgAnnotationPoint[] = this.getPointsFromSession(ev.session, false) - const annotationsToBeAdded: annotation.UnionAnnotation[] = [] - for (const pt of allInRoiPoints) { - annotationsToBeAdded.push({ - "@id": pt.id, - color: annotation.AnnotationColor.RED, - openminds: { - "@id": pt.id, - "@type": "https://openminds.ebrains.eu/sands/CoordinatePoint", - coordinateSpace: { - "@id": this.space["@id"] - }, - coordinates: pt.point.map(v => { - return { - value: v / 1e6 - } - }) - }, - name: pt.description || "Untitled" - }) - } - for (const pt of allNonInRoiPoints) { - annotationsToBeAdded.push({ - "@id": pt.id, - color: annotation.AnnotationColor.WHITE, - openminds: { - "@id": pt.id, - "@type": "https://openminds.ebrains.eu/sands/CoordinatePoint", - coordinateSpace: { - "@id": this.space["@id"] - }, - coordinates: pt.point.map(v => { - return { - value: v / 1e6 - } - }) - }, - name: pt.description || "Untitled" - }) - } - this.addedAnnotations = annotationsToBeAdded - this.store.dispatch( - annotation.actions.addAnnotations({ - annotations: annotationsToBeAdded - }) - ) - } - } - ieegOnDefocus(ev: IeegOnDefocusEvent){ - if (ev.session) { - const allInRoiPoints: TNgAnnotationPoint[] = this.getPointsFromSession(ev.session, true) - const allNonInRoiPoints: TNgAnnotationPoint[] = this.getPointsFromSession(ev.session, false) - - this.store.dispatch( - annotation.actions.rmAnnotations({ - annotations: [...allInRoiPoints, ...allNonInRoiPoints].map(p => { - return { "@id": p.id } - }) - }) - ) - } - } - - ngOnDestroy(): void { - this.store.dispatch( - annotation.actions.rmAnnotations({ - annotations: this.addedAnnotations - }) - ) - } - - constructor( - private store: Store - ){ - - } - - private getPointsFromSession(session: Session<string>, inRoi: boolean):TNgAnnotationPoint[]{ - const allPoints: TNgAnnotationPoint[] = [] - for (const electrodeKey in session.electrodes) { - const electrode = session.electrodes[electrodeKey] - const points = this.getPointsFromElectrode(electrode, inRoi) - allPoints.push(...points) - } - return allPoints.map(pt => { - return { - ...pt, - id: `${session.sub_id}:${pt.id}` - } - }) - } - - private getPointsFromElectrode(electrode: Electrode<string>, inRoi: boolean): TNgAnnotationPoint[] { - const allPoints: TNgAnnotationPoint[] = [] - for (const ctptKey in electrode.contact_points) { - const ctpt = electrode.contact_points[ctptKey] - if (!inRoi !== !ctpt.inRoi) { - continue - } - const point = this.getPointFromCtPt(ctpt) - allPoints.push(point) - } - return allPoints.map(pt => { - return { - ...pt, - id: `${electrode.electrode_id}:${pt.id}` - } - }) - } - - private getPointFromCtPt(ctpt: ContactPoint<string>): TNgAnnotationPoint { - return { - id: ctpt.id, - point: ctpt.point.coordinates.map(coord => coord.value * 1e6 ) as [number, number, number], - type: 'point' - } - } -} diff --git a/tmpFeatures/entry/entry.style.css b/tmpFeatures/entry/entry.style.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/tmpFeatures/entry/entry.template.html b/tmpFeatures/entry/entry.template.html deleted file mode 100644 index 38a00def6..000000000 --- a/tmpFeatures/entry/entry.template.html +++ /dev/null @@ -1,22 +0,0 @@ -<div [ngSwitch]="feature?.['@type']"> - <sxplr-sapiviews-features-receptor-entry - *ngSwitchCase="featureType.receptor" - [sxplr-sapiviews-features-receptor-atlas]="atlas" - [sxplr-sapiviews-features-receptor-parcellation]="parcellation" - [sxplr-sapiviews-features-receptor-template]="space" - [sxplr-sapiviews-features-receptor-region]="region" - [sxplr-sapiviews-features-receptor-featureid]="feature['@id']"> - </sxplr-sapiviews-features-receptor-entry> - <sxplr-sapiviews-features-ieeg-ieegdataset - *ngSwitchCase="featureType.ieeg" - [sxplr-sapiviews-features-ieeg-ieegdataset-atlas]="atlas" - [sxplr-sapiviews-features-ieeg-ieegdataset-space]="space" - [sxplr-sapiviews-features-ieeg-ieegdataset-parcellation]="parcellation" - [sxplr-sapiviews-features-ieeg-ieegdataset-region]="region" - [sxplr-sapiviews-features-ieeg-ieegdataset-feature]="feature" - (sxplr-sapiviews-features-ieeg-ieegdataset-on-focus)="ieegOnFocus($event)" - (sxplr-sapiviews-features-ieeg-ieegdataset-on-defocus)="ieegOnDefocus($event)" - > - - </sxplr-sapiviews-features-ieeg-ieegdataset> -</div> diff --git a/tmpFeatures/entryListItem/entryListItem.component.ts b/tmpFeatures/entryListItem/entryListItem.component.ts deleted file mode 100644 index 8008affe3..000000000 --- a/tmpFeatures/entryListItem/entryListItem.component.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { ChangeDetectionStrategy, Component, Input } from "@angular/core"; -import { SapiFeatureModel } from "src/atlasComponents/sapi"; -import { CleanedIeegDataset, CLEANED_IEEG_DATASET_TYPE, SapiDatasetModel, SapiParcellationFeatureMatrixModel, SapiRegionalFeatureReceptorModel, SapiSerializationErrorModel, SapiVOIDataResponse, SxplrCleanedFeatureModel } from "src/atlasComponents/sapi/type"; - -@Component({ - selector: `sxplr-sapiviews-features-entry-list-item`, - templateUrl: `./entryListItem.template.html`, - styleUrls: [ - `./entryListItem.style.css` - ], - changeDetection: ChangeDetectionStrategy.OnPush, -}) - -export class SapiViewsFeaturesEntryListItem{ - @Input('sxplr-sapiviews-features-entry-list-item-feature') - feature: SapiFeatureModel | SxplrCleanedFeatureModel - - @Input('sxplr-sapiviews-features-entry-list-item-ripple') - ripple = true - - get label(): string{ - if (!this.feature) return null - const { '@type': type } = this.feature - if ( - type === "https://openminds.ebrains.eu/core/DatasetVersion" || - type === "siibra/features/cells" || - type === "siibra/features/receptor" || - type === "siibra/features/voi" || - type === CLEANED_IEEG_DATASET_TYPE - ) { - return (this.feature as (SapiDatasetModel | SapiRegionalFeatureReceptorModel | SapiVOIDataResponse | CleanedIeegDataset) ).metadata.fullName - } - - if ( - type === "siibra/features/connectivity" || - type === "siibra/features/connectivity/streamlineCounts" - ) { - return (this.feature as SapiParcellationFeatureMatrixModel).name - } - if (type === "spy/serialization-error") { - return (this.feature as SapiSerializationErrorModel).message - } - return "Unknown type" - } -} diff --git a/tmpFeatures/entryListItem/entryListItem.style.css b/tmpFeatures/entryListItem/entryListItem.style.css deleted file mode 100644 index 58f6c43f5..000000000 --- a/tmpFeatures/entryListItem/entryListItem.style.css +++ /dev/null @@ -1,5 +0,0 @@ -:host span -{ - overflow: hidden; - white-space: nowrap; -} diff --git a/tmpFeatures/entryListItem/entryListItem.template.html b/tmpFeatures/entryListItem/entryListItem.template.html deleted file mode 100644 index fc1ac7920..000000000 --- a/tmpFeatures/entryListItem/entryListItem.template.html +++ /dev/null @@ -1,17 +0,0 @@ -<div matRipple [matRippleDisabled]="!ripple" - class="sxplr-p-2"> - - <mat-chip-list - *ngIf="feature | featureBadgeFlag" - class="sxplr-scale-80 transform-origin-left-center sxplr-pe-none"> - <mat-chip - [color]="feature | featureBadgeColour" - selected> - {{ feature | featureBadgeName }} - </mat-chip> - </mat-chip-list> - - <span class="d-block mat-body"> - {{ label }} - </span> -</div> diff --git a/tmpFeatures/entryListItem/entryListitem.stories.ts b/tmpFeatures/entryListItem/entryListitem.stories.ts deleted file mode 100644 index a93cd9816..000000000 --- a/tmpFeatures/entryListItem/entryListitem.stories.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { CommonModule } from "@angular/common" -import { Meta, moduleMetadata, Story } from "@storybook/angular" -import { SapiFeatureModel } from "src/atlasComponents/sapi" -import { getHoc1RightFeatures, getHoc1RightSpatialFeatures, getJba29Features, provideDarkTheme } from "src/atlasComponents/sapi/stories.base" -import { AngularMaterialModule } from "src/sharedModules" -import { SapiViewsFeaturesEntryListItem } from "./entryListItem.component" -import { Component, EventEmitter, Input, Output } from "@angular/core" -import { SapiViewsFeaturesModule } from ".." - -@Component({ - selector: `feature-list-item-wrapper`, - template: ` - <mat-card> - <sxplr-sapiviews-features-entry-list-item - *ngFor="let feat of features" - (click)="clicked.emit(feat)" - [sxplr-sapiviews-features-entry-list-item-feature]="feat" - [sxplr-sapiviews-features-entry-list-item-ripple]="ripple"> - </sxplr-sapiviews-features-entry-list-item> - </mat-card> - ` -}) - -class FeatureListItemWrapper { - features: SapiFeatureModel[] = [] - - @Input() - ripple: boolean = true - - @Output() - clicked = new EventEmitter() -} - -export default { - component: FeatureListItemWrapper, - decorators: [ - moduleMetadata({ - imports: [ - CommonModule, - AngularMaterialModule, - SapiViewsFeaturesModule, - ], - declarations: [], - providers: [ - ...provideDarkTheme, - ], - }) - ], - -} as Meta - -const Template: Story<SapiViewsFeaturesEntryListItem> = (args: SapiViewsFeaturesEntryListItem, { loaded }) => { - const { features } = loaded - return ({ - props: { - ...args, - features - }, - }) -} - - -export const RegionalFeatures = Template.bind({}) -RegionalFeatures.args = { - -} -RegionalFeatures.loaders = [ - async () => { - const features = [ - ...(await getHoc1RightSpatialFeatures()), - ...(await getHoc1RightFeatures()) - ] - return { - features - } - } -] - -export const ParcellationFeatures = Template.bind({}) -ParcellationFeatures.loaders = [ - async () => { - - const features = await getJba29Features() - return { - features - } - } -] \ No newline at end of file diff --git a/tmpFeatures/featureBadgeColor.pipe.ts b/tmpFeatures/featureBadgeColor.pipe.ts deleted file mode 100644 index 474d6a2ad..000000000 --- a/tmpFeatures/featureBadgeColor.pipe.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Pipe, PipeTransform } from "@angular/core"; -import { SapiFeatureModel, SxplrCleanedFeatureModel, CLEANED_IEEG_DATASET_TYPE } from "src/atlasComponents/sapi"; - -@Pipe({ - name: 'featureBadgeColour', - pure: true -}) - -export class FeatureBadgeColourPipe implements PipeTransform{ - public transform(regionalFeature: SapiFeatureModel|SxplrCleanedFeatureModel) { - if (regionalFeature['@type'] === "siibra/features/receptor") { - return "accent" - } - if (regionalFeature['@type'] === CLEANED_IEEG_DATASET_TYPE) { - return "primary" - } - return "default" - } -} diff --git a/tmpFeatures/featureBadgeFlag.pipe.ts b/tmpFeatures/featureBadgeFlag.pipe.ts deleted file mode 100644 index 986edffac..000000000 --- a/tmpFeatures/featureBadgeFlag.pipe.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Pipe, PipeTransform } from "@angular/core"; -import { SapiFeatureModel, SxplrCleanedFeatureModel, CLEANED_IEEG_DATASET_TYPE } from "src/atlasComponents/sapi"; - -@Pipe({ - name: 'featureBadgeFlag', - pure: true -}) - -export class FeatureBadgeFlagPipe implements PipeTransform{ - public transform(regionalFeature: SapiFeatureModel|SxplrCleanedFeatureModel) { - return regionalFeature['@type'] === "siibra/features/receptor" - || regionalFeature['@type'] === CLEANED_IEEG_DATASET_TYPE - } -} diff --git a/tmpFeatures/featureBadgeName.pipe.ts b/tmpFeatures/featureBadgeName.pipe.ts deleted file mode 100644 index 33570440c..000000000 --- a/tmpFeatures/featureBadgeName.pipe.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Pipe, PipeTransform } from "@angular/core"; -import { SapiFeatureModel, SxplrCleanedFeatureModel, CLEANED_IEEG_DATASET_TYPE } from "src/atlasComponents/sapi"; - -@Pipe({ - name: 'featureBadgeName', - pure: true -}) - -export class FeatureBadgeNamePipe implements PipeTransform{ - public transform(regionalFeature: SapiFeatureModel|SxplrCleanedFeatureModel) { - if (regionalFeature['@type'] === "siibra/features/receptor") { - return "receptor density" - } - if (regionalFeature["@type"] === CLEANED_IEEG_DATASET_TYPE) { - return "IEEG dataset" - } - return null - } -} diff --git a/tmpFeatures/ieeg/ieegDataset/ieegDataset.component.ts b/tmpFeatures/ieeg/ieegDataset/ieegDataset.component.ts deleted file mode 100644 index de23194ff..000000000 --- a/tmpFeatures/ieeg/ieegDataset/ieegDataset.component.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Component, EventEmitter, Input, OnChanges, OnDestroy, Output, SimpleChanges } from "@angular/core"; -import { BehaviorSubject, forkJoin } from "rxjs"; -import { SAPI } from "src/atlasComponents/sapi/sapi.service"; -import { CleanedIeegDataset, cleanIeegSessionDatasets, SapiAtlasModel, SapiIeegSessionModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi/type"; - -export type Session<SId extends string> = CleanedIeegDataset['sessions'][SId] -export type Electrode<EId extends string> = Session<string>['electrodes'][EId] -export type ContactPoint<CId extends string> = Electrode<string>['contact_points'][CId] - -export type IeegOnFocusEvent = { - contactPoint: ContactPoint<string> - electrode: Electrode<string> - session: Session<string> -} - -export type IeegOnDefocusEvent = { - contactPoint: ContactPoint<string> - electrode: Electrode<string> - session: Session<string> -} - -@Component({ - selector: `sxplr-sapiviews-features-ieeg-ieegdataset`, - templateUrl: `./ieegDataset.template.html`, - styleUrls: [ - `./ieegDataset.style.css` - ] -}) - -export class IEEGDatasetCmp implements OnChanges{ - - @Input('sxplr-sapiviews-features-ieeg-ieegdataset-atlas') - public atlas: SapiAtlasModel - - @Input('sxplr-sapiviews-features-ieeg-ieegdataset-space') - public space: SapiSpaceModel - - @Input('sxplr-sapiviews-features-ieeg-ieegdataset-parcellation') - public parcellation: SapiParcellationModel - - @Input('sxplr-sapiviews-features-ieeg-ieegdataset-region') - public region: SapiRegionModel - - /** - * we must assume that the passed feature does not have the detail flag on - * We need to fetch the - */ - @Input('sxplr-sapiviews-features-ieeg-ieegdataset-feature') - public feature: CleanedIeegDataset - public detailedFeature: CleanedIeegDataset - - @Output('sxplr-sapiviews-features-ieeg-ieegdataset-on-focus') - public onFocus = new EventEmitter<IeegOnFocusEvent>() - - @Output('sxplr-sapiviews-features-ieeg-ieegdataset-on-defocus') - public onDefocus = new EventEmitter<IeegOnDefocusEvent>() - - public busy$ = new BehaviorSubject<boolean>(false) - - ngOnChanges(changes: SimpleChanges): void { - if (!this.feature) { - return - } - if (this.feature && this.feature["@type"] !== "sxplr/cleanedIeegDataset") { - throw new Error(`expected @type to be sxplr-cleaned-ieeg-dataset, but is ${this.feature['@type']}.`) - } - this.busy$.next(true) - - forkJoin( - Object.entries(this.feature.sessions).map(([ key, session ]) => { - return this.sapi.getSpace(this.atlas["@id"], this.space["@id"]).getFeatureInstance(session["@id"], { parcellationId: this.parcellation["@id"], region: this.region.name }) - }) - ).subscribe(feats => { - - const ieegSessions: SapiIeegSessionModel[] = feats.filter(feat => feat["@type"] === "siibra/features/ieegSession") - const features = cleanIeegSessionDatasets(ieegSessions) - const foundFeat = features.find(f => f["@id"] === this.feature["@id"]) - if (foundFeat) { - this.detailedFeature = foundFeat - } - this.busy$.next(false) - }) - } - - public onContactPointClicked(cpt: ContactPoint<string>, ele: Electrode<string>, sess: Session<string>){ - this.onFocus.emit({ - contactPoint: cpt, - electrode: ele, - session: sess - }) - } - - public onPanelOpen(session: Session<string>){ - this.onFocus.emit({ - contactPoint: null, - electrode: null, - session: session - }) - } - - public onPanelClose(session: Session<string>){ - this.onDefocus.emit({ - contactPoint: null, - electrode: null, - session: session - }) - } - - constructor(private sapi: SAPI){ - - } - -} diff --git a/tmpFeatures/ieeg/ieegDataset/ieegDataset.stories.ts b/tmpFeatures/ieeg/ieegDataset/ieegDataset.stories.ts deleted file mode 100644 index c9f08880e..000000000 --- a/tmpFeatures/ieeg/ieegDataset/ieegDataset.stories.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular" -import { SAPI, SapiAtlasModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi" -import { getHoc1Right, getHumanAtlas, getJba29, getMni152, provideDarkTheme, getMni152SpatialFeatureHoc1Right } from "src/atlasComponents/sapi/stories.base" -import { SxplrSapiViewsFeaturesIeegModule } from ".." -import { Component } from "@angular/core" -import { cleanIeegSessionDatasets, SapiSpatialFeatureModel } from "src/atlasComponents/sapi/type" -import { action } from "@storybook/addon-actions" - -@Component({ - selector: 'ieeg-entry-wrapper-cmp', - template: ` - <sxplr-sapiviews-features-ieeg-ieegdataset - [sxplr-sapiviews-features-ieeg-ieegdataset-atlas]="atlas" - [sxplr-sapiviews-features-ieeg-ieegdataset-space]="template" - [sxplr-sapiviews-features-ieeg-ieegdataset-parcellation]="parcellation" - [sxplr-sapiviews-features-ieeg-ieegdataset-region]="region" - [sxplr-sapiviews-features-ieeg-ieegdataset-feature]="feature" - (sxplr-sapiviews-features-ieeg-ieegdataset-on-focus)="handleCtptClick($event)" - (sxplr-sapiviews-features-ieeg-ieegdataset-on-defocus)="handleOnDeFocus($event)" - > - </sxplr-sapiviews-features-ieeg-ieegdataset> - `, - styles: [ - ` - :host - { - display: block; - width: 20rem; - } - ` - ] -}) -class EntryWrappercls { - atlas: SapiAtlasModel - template: SapiSpaceModel - feature: SapiSpatialFeatureModel - parcellation: SapiParcellationModel - region: SapiRegionModel - - handleOnFocus(cpt: unknown){} - handleOnDeFocus(cpt: unknown) {} -} - -export default { - component: EntryWrappercls, - decorators: [ - moduleMetadata({ - imports: [ - SxplrSapiViewsFeaturesIeegModule, - ], - providers: [ - SAPI, - ...provideDarkTheme, - ], - declarations: [ - EntryWrappercls - ] - }) - ], -} as Meta - -const Template: Story<EntryWrappercls> = (args: EntryWrappercls, { loaded }) => { - const { atlas, parc, space, region, feature } = loaded - return ({ - props: { - ...args, - atlas: atlas, - parcellation: parc, - template: space, - region: region, - feature, - handleOnFocus: action('handleOnFocus'), - handleOnDeFocus: action('handleOnDeFocus') - }, - }) -} - -const loadFeat = async () => { - const atlas = await getHumanAtlas() - const space = await getMni152() - const parc = await getJba29() - const region = await getHoc1Right() - - const features = await getMni152SpatialFeatureHoc1Right() - const spatialFeats = features.filter(f => f["@type"] === "siibra/features/ieegSession") - const feature = cleanIeegSessionDatasets(spatialFeats)[0] - return { - atlas, - space, - parc, - region, - feature - } -} - -export const Default = Template.bind({}) -Default.args = { - -} -Default.loaders = [ - async () => { - const { - atlas, - space, - feature, - parc, - region, - } = await loadFeat() - return { - atlas, space, feature, parc, region - } - } -] diff --git a/tmpFeatures/ieeg/ieegDataset/ieegDataset.style.css b/tmpFeatures/ieeg/ieegDataset/ieegDataset.style.css deleted file mode 100644 index 1c554eef7..000000000 --- a/tmpFeatures/ieeg/ieegDataset/ieegDataset.style.css +++ /dev/null @@ -1,4 +0,0 @@ -mat-form-field -{ - width: 100%; -} diff --git a/tmpFeatures/ieeg/ieegDataset/ieegDataset.template.html b/tmpFeatures/ieeg/ieegDataset/ieegDataset.template.html deleted file mode 100644 index af7464f5e..000000000 --- a/tmpFeatures/ieeg/ieegDataset/ieegDataset.template.html +++ /dev/null @@ -1,112 +0,0 @@ -<spinner-cmp *ngIf="busy$ | async; else resultTmpl"> -</spinner-cmp> - -<ng-template #resultTmpl> - - <mat-accordion *ngIf="!!detailedFeature"> - <ng-template - ngFor - [ngForOf]="detailedFeature.sessions | keyvalue" - let-sessionKeyVal> - - <ng-template - [ngIf]="sessionKeyVal.value.inRoi" - [ngTemplateOutlet]="sessionTmpl" - [ngTemplateOutletContext]="{ - $implicit: sessionKeyVal.value - }"> - - </ng-template> - - </ng-template> - </mat-accordion> - -</ng-template> - -<!-- session template --> -<ng-template #sessionTmpl let-session> - <mat-expansion-panel - (opened)="onPanelOpen(session)" - (closed)="onPanelClose(session)"> - <mat-expansion-panel-header> - SessionID: {{ session.sub_id }} - </mat-expansion-panel-header> - - <ng-template matExpansionPanelContent> - <ng-template - ngFor - [ngForOf]="session.electrodes | keyvalue | inRoi" - let-electrodeKeyVal> - <ng-template - [ngTemplateOutlet]="electrodeTmpl" - [ngTemplateOutletContext]="{ - electrode: electrodeKeyVal.value, - session: session - }"> - - </ng-template> - </ng-template> - - <mat-divider></mat-divider> - <ng-template - ngFor - [ngForOf]="session.electrodes | keyvalue | inRoi : false" - let-electrodeKeyVal> - <div class="sxplr-very-muted"> - <ng-template - [ngTemplateOutlet]="electrodeTmpl" - [ngTemplateOutletContext]="{ - electrode: electrodeKeyVal.value, - session: session - }"> - - </ng-template> - </div> - </ng-template> - </ng-template> - </mat-expansion-panel> -</ng-template> - -<!-- electrode template --> -<ng-template - #electrodeTmpl - let-electrode="electrode" - let-session="session"> - <mat-form-field appearance="fill"> - <mat-label> - ElectrodeID: {{ electrode.electrode_id }} - </mat-label> - <mat-chip-list> - <ng-template - ngFor - [ngForOf]="electrode.contact_points | keyvalue" - let-contactPointKeyVal> - - <ng-template - [ngTemplateOutlet]="contactPointTmpl" - [ngTemplateOutletContext]="{ - contactPointKey: contactPointKeyVal.key, - contactPoint: contactPointKeyVal.value, - electrode: electrode, - session: session - }"> - </ng-template> - </ng-template> - </mat-chip-list> - </mat-form-field> -</ng-template> - -<!-- contact point template --> -<ng-template - #contactPointTmpl - let-contactPoint="contactPoint" - let-key="contactPointKey" - let-electrode="electrode" - let-session="session"> - <mat-chip - (click)="onContactPointClicked(contactPoint, electrode, session)" - [color]="contactPoint.inRoi ? 'primary' : 'default'" - selected> - {{ key }} - </mat-chip> -</ng-template> \ No newline at end of file diff --git a/tmpFeatures/ieeg/inRoi.pipe.ts b/tmpFeatures/ieeg/inRoi.pipe.ts deleted file mode 100644 index 4f215c8cc..000000000 --- a/tmpFeatures/ieeg/inRoi.pipe.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Pipe, PipeTransform } from "@angular/core"; - -interface InRoi { - key: string - value: { - inRoi: boolean - } -} - -@Pipe({ - name: 'inRoi', - pure: true -}) - -export class InRoiPipe implements PipeTransform{ - public transform(list: InRoi[], inroi=true): InRoi[] { - return list.filter(it => it.value.inRoi === inroi) - } -} diff --git a/tmpFeatures/ieeg/index.ts b/tmpFeatures/ieeg/index.ts deleted file mode 100644 index 757808e77..000000000 --- a/tmpFeatures/ieeg/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { IEEGDatasetCmp, IeegOnFocusEvent, IeegOnDefocusEvent, ContactPoint, Electrode, Session } from "./ieegDataset/ieegDataset.component" -export { SxplrSapiViewsFeaturesIeegModule } from "./module" \ No newline at end of file diff --git a/tmpFeatures/ieeg/module.ts b/tmpFeatures/ieeg/module.ts deleted file mode 100644 index c91161eac..000000000 --- a/tmpFeatures/ieeg/module.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { CommonModule } from "@angular/common"; -import { NgModule } from "@angular/core"; -import { MatChipsModule } from "@angular/material/chips"; -import { MatDividerModule } from "@angular/material/divider"; -import { MatExpansionModule } from "@angular/material/expansion"; -import { MatFormFieldModule } from "@angular/material/form-field"; -import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; -import { SAPIModule } from "src/atlasComponents/sapi/module"; -import { SpinnerModule } from "src/components/spinner"; -import { IEEGDatasetCmp } from "./ieegDataset/ieegDataset.component"; -import { InRoiPipe } from "./inRoi.pipe"; - -@NgModule({ - imports: [ - CommonModule, - MatExpansionModule, - MatChipsModule, - MatFormFieldModule, - MatDividerModule, - BrowserAnimationsModule, - SpinnerModule, - SAPIModule, - ], - declarations: [ - IEEGDatasetCmp, - InRoiPipe, - ], - exports: [ - IEEGDatasetCmp, - ] -}) - -export class SxplrSapiViewsFeaturesIeegModule{} \ No newline at end of file diff --git a/tmpFeatures/index.ts b/tmpFeatures/index.ts deleted file mode 100644 index 89e1fafba..000000000 --- a/tmpFeatures/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { - SapiViewsFeaturesModule -} from "./module" - -export { - SapiViewsFeaturesVoiQuery -} from "./voi" diff --git a/tmpFeatures/module.ts b/tmpFeatures/module.ts deleted file mode 100644 index 54651dc28..000000000 --- a/tmpFeatures/module.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { CommonModule, DOCUMENT } from "@angular/common" -import { NgModule } from "@angular/core" -import { AngularMaterialModule } from "src/sharedModules" -import { appendScriptFactory, APPEND_SCRIPT_TOKEN } from "src/util/constants" -import { FeatureEntryCmp } from "./entry/entry.component" -import { SapiViewsFeaturesEntryListItem } from "./entryListItem/entryListItem.component" -import { FeatureBadgeColourPipe } from "./featureBadgeColor.pipe" -import { FeatureBadgeFlagPipe } from "./featureBadgeFlag.pipe" -import { FeatureBadgeNamePipe } from "./featureBadgeName.pipe" -import * as ieeg from "./ieeg" -import * as receptor from "./receptors" -import * as voi from "./voi" -import { OrderFilterFeaturesPipe } from "./orderFilterFeatureList.pipe" - -const { - SxplrSapiViewsFeaturesIeegModule -} = ieeg -const { - ReceptorViewModule -} = receptor -const { SapiViewsFeaturesVoiModule } = voi - -@NgModule({ - imports: [ - CommonModule, - ReceptorViewModule, - SxplrSapiViewsFeaturesIeegModule, - AngularMaterialModule, - SapiViewsFeaturesVoiModule, - ], - declarations: [ - FeatureEntryCmp, - FeatureBadgeNamePipe, - FeatureBadgeColourPipe, - FeatureBadgeFlagPipe, - SapiViewsFeaturesEntryListItem, - OrderFilterFeaturesPipe, - ], - providers: [ - { - provide: APPEND_SCRIPT_TOKEN, - useFactory: appendScriptFactory, - deps: [ DOCUMENT ] - } - ], - exports: [ - FeatureEntryCmp, - SapiViewsFeaturesEntryListItem, - SapiViewsFeaturesVoiModule, - OrderFilterFeaturesPipe, - ] -}) -export class SapiViewsFeaturesModule{} diff --git a/tmpFeatures/orderFilterFeatureList.pipe.ts b/tmpFeatures/orderFilterFeatureList.pipe.ts deleted file mode 100644 index 382862b03..000000000 --- a/tmpFeatures/orderFilterFeatureList.pipe.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Pipe, PipeTransform } from "@angular/core"; -import { CLEANED_IEEG_DATASET_TYPE, SapiFeatureModel, SxplrCleanedFeatureModel } from "src/atlasComponents/sapi/type"; -import { environment } from "src/environments/environment" - -type PipableFeatureType = SapiFeatureModel | SxplrCleanedFeatureModel - -type ArrayOperation<T extends boolean | number> = (input: PipableFeatureType) => T - -const FILTER_FN: ArrayOperation<boolean> = feature => { - return feature["@type"] !== "siibra/features/cells" -} - -const ORDER_LIST: ArrayOperation<number> = feature => { - if (feature["@type"] === "siibra/features/receptor") return -4 - if (feature["@type"] === CLEANED_IEEG_DATASET_TYPE) return -3 - if (feature['@type'] === "https://openminds.ebrains.eu/core/DatasetVersion") return 2 - return 0 -} - -@Pipe({ - name: 'orderFilterFeatures', - pure: true -}) - -export class OrderFilterFeaturesPipe implements PipeTransform{ - public transform(inputFeatures: PipableFeatureType[]): PipableFeatureType[] { - return inputFeatures - .filter(f => { - /** - * if experimental flag is set, do not filter out anything - */ - if (environment.EXPERIMENTAL_FEATURE_FLAG) return true - return FILTER_FN(f) - }) - .sort((a, b) => ORDER_LIST(a) - ORDER_LIST(b)) - } -} diff --git a/tmpFeatures/receptors/autoradiography/autoradiograph.stories.ts b/tmpFeatures/receptors/autoradiography/autoradiograph.stories.ts deleted file mode 100644 index 093ec6a11..000000000 --- a/tmpFeatures/receptors/autoradiography/autoradiograph.stories.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { CommonModule } from "@angular/common" -import { HttpClientModule } from "@angular/common/http" -import { Component, ViewChild } from "@angular/core" -import { FormsModule } from "@angular/forms" -import { BrowserAnimationsModule } from "@angular/platform-browser/animations" -import { Meta, moduleMetadata, Story } from "@storybook/angular" -import { SAPI, SapiAtlasModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi" -import { getHoc1RightFeatureDetail, getHoc1RightFeatures, getHoc1Right, getHumanAtlas, getJba29, getMni152 } from "src/atlasComponents/sapi/stories.base" -import { SapiRegionalFeatureReceptorModel } from "src/atlasComponents/sapi/type" -import { AngularMaterialModule } from "src/sharedModules" -import { Autoradiography } from "./autoradiography.component" - -@Component({ - selector: 'autoradiograph-wrapper-cmp', - template: ` - <mat-form-field appearance="fill"> - <mat-select [(ngModel)]="selectedSymbol"> - <mat-option value="" disabled> - --select-- - </mat-option> - - <mat-option [value]="option" - *ngFor="let option of options"> - {{ option }} - </mat-option> - </mat-select> - </mat-form-field> - <sxplr-sapiviews-features-receptor-autoradiograph - class="d-inline-block w-100 h-100" - [sxplr-sapiviews-features-receptor-atlas]="atlas" - [sxplr-sapiviews-features-receptor-parcellation]="parcellation" - [sxplr-sapiviews-features-receptor-template]="template" - [sxplr-sapiviews-features-receptor-region]="region" - [sxplr-sapiviews-features-receptor-featureid]="featureId" - [sxplr-sapiviews-features-receptor-data]="feature" - [sxplr-sapiviews-features-receptor-autoradiograph-selected-symbol]="selectedSymbol" - > - </sxplr-sapiviews-features-receptor-autoradiograph> - `, - styles: [ - ` - :host - { - display: block; - max-width: 24rem; - max-height: 24rem; - } - ` - ] -}) -class AutoRadiographWrapperCls { - atlas: SapiAtlasModel - parcellation: SapiParcellationModel - template: SapiSpaceModel - region: SapiRegionModel - - feature: SapiRegionalFeatureReceptorModel - featureId: string - - @ViewChild(Autoradiography) - ar: Autoradiography - - selectedSymbol: string - - get options(){ - return Object.keys(this.feature?.data?.autoradiographs || this.ar?.receptorData?.data?.autoradiographs || {}) - } -} - -export default { - component: AutoRadiographWrapperCls, - decorators: [ - moduleMetadata({ - imports: [ - CommonModule, - AngularMaterialModule, - HttpClientModule, - BrowserAnimationsModule, - FormsModule, - ], - providers: [ - SAPI - ], - declarations: [ - Autoradiography - ] - }) - ], -} as Meta - -const Template: Story<AutoRadiographWrapperCls> = (args: AutoRadiographWrapperCls, { loaded }) => { - const { atlas, parc, space, region, featureId, feature } = loaded - return ({ - props: { - ...args, - atlas: atlas, - parcellation: parc, - template: space, - region: region, - feature, - featureId, - }, - }) -} - -const loadFeat = async () => { - const atlas = await getHumanAtlas() - const parc = await getJba29() - const region = await getHoc1Right() - const space = await getMni152() - const features = await getHoc1RightFeatures() - const receptorfeat = features.find(f => f['@type'] === "siibra/features/receptor") - const feature = await getHoc1RightFeatureDetail(receptorfeat["@id"]) - return { - atlas, - parc, - space, - region, - featureId: receptorfeat["@id"], - feature - } -} - -export const Default = Template.bind({}) -Default.args = { - -} -Default.loaders = [ - async () => { - const { atlas, parc, space, region, featureId } = await loadFeat() - return { - atlas, parc, space, region, featureId - } - } -] - -export const LoadViaDirectlyInjectData = Template.bind({}) -LoadViaDirectlyInjectData.loaders = [ - async () => { - - const { feature } = await loadFeat() - return { - feature - } - } -] \ No newline at end of file diff --git a/tmpFeatures/receptors/autoradiography/autoradiography.component.ts b/tmpFeatures/receptors/autoradiography/autoradiography.component.ts deleted file mode 100644 index ecd059f0a..000000000 --- a/tmpFeatures/receptors/autoradiography/autoradiography.component.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { AfterViewInit, Component, ElementRef, Input, OnChanges, SimpleChanges } from "@angular/core"; -import { SAPI } from "src/atlasComponents/sapi"; -import { PARSE_TYPEDARRAY } from "src/atlasComponents/sapi/sapi.service"; -import { BaseReceptor } from "../base"; - -@Component({ - selector: `sxplr-sapiviews-features-receptor-autoradiograph`, - templateUrl: './autoradiography.template.html', - styleUrls: [ - './autoradiography.style.css' - ], - exportAs: 'sxplrSapiViewsFeaturesReceptorAR' -}) - -export class Autoradiography extends BaseReceptor implements OnChanges, AfterViewInit{ - - @Input('sxplr-sapiviews-features-receptor-autoradiograph-selected-symbol') - selectedSymbol: string - - private pleaseRender = false - - width: number - height: number - renderBuffer: Uint8ClampedArray - - async ngOnChanges(simpleChanges: SimpleChanges) { - await super.ngOnChanges(simpleChanges) - if (!this.receptorData) { - return - } - if (this.selectedSymbol) { - const fp = this.receptorData.data.autoradiographs[this.selectedSymbol] - if (!fp) { - this.error = `selectedSymbol ${this.selectedSymbol} cannot be found. Valid symbols are ${Object.keys(this.receptorData.data.autoradiographs)}` - return - } - const { "x-width": width, "x-height": height } = fp - - this.width = width - this.height = height - - const { result } = await this.sapi.processNpArrayData<PARSE_TYPEDARRAY.CANVAS_FORTRAN_RGBA>(fp, PARSE_TYPEDARRAY.CANVAS_FORTRAN_RGBA) - this.renderBuffer = result - this.rerender() - } - } - constructor(sapi: SAPI, private el: ElementRef){ - super(sapi) - } - - ngAfterViewInit(): void { - if (this.pleaseRender) this.rerender() - } - - rerender(){ - this.dataBlobAvailable = false - if (!this.el || !this.renderBuffer) { - this.pleaseRender = true - return - } - - const arContainer = (this.el.nativeElement as HTMLElement) - while (arContainer.firstChild) { - arContainer.removeChild(arContainer.firstChild) - } - - const canvas = document.createElement("canvas") - canvas.height = this.height - canvas.width = this.width - arContainer.appendChild(canvas) - const ctx = canvas.getContext("2d") - const imgData = ctx.createImageData(this.width, this.height) - imgData.data.set(this.renderBuffer) - ctx.putImageData(imgData, 0, 0) - - canvas.toBlob(blob => { - this.dataBlobAvailable = true - this.dataBlob$.next(blob) - }) - this.pleaseRender = false - } -} diff --git a/tmpFeatures/receptors/autoradiography/autoradiography.style.css b/tmpFeatures/receptors/autoradiography/autoradiography.style.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/tmpFeatures/receptors/autoradiography/autoradiography.template.html b/tmpFeatures/receptors/autoradiography/autoradiography.template.html deleted file mode 100644 index e69de29bb..000000000 diff --git a/tmpFeatures/receptors/base.ts b/tmpFeatures/receptors/base.ts deleted file mode 100644 index b3107f4e9..000000000 --- a/tmpFeatures/receptors/base.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { Directive, Input, SimpleChanges } from "@angular/core"; -import { BehaviorSubject } from "rxjs"; -import { SAPI, SapiAtlasModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi"; -import { TabularFeature } from "src/atlasComponents/sapi/sxplrTypes" - -@Directive() -export abstract class BaseReceptor{ - - @Input('sxplr-sapiviews-features-receptor-atlas') - atlas: SapiAtlasModel - - @Input('sxplr-sapiviews-features-receptor-parcellation') - parcellation: SapiParcellationModel - - @Input('sxplr-sapiviews-features-receptor-template') - template: SapiSpaceModel - - @Input('sxplr-sapiviews-features-receptor-region') - region: SapiRegionModel - - @Input('sxplr-sapiviews-features-receptor-featureid') - featureId: string - - @Input('sxplr-sapiviews-features-receptor-data') - receptorData: TabularFeature<number> - - error: string - - async ngOnChanges(simpleChanges: SimpleChanges) { - if (simpleChanges.receptorData?.currentValue) { - this.rerender() - return - } - if (this.canFetch) { - this.receptorData = await this.fetchReceptorData() - this.rerender() - } - } - - private get canFetch() { - if (!this.atlas) { - this.error = `atlas needs to be defined, but is not` - return false - } - if (!this.parcellation) { - this.error = `parcellation needs to be defined, but is not` - return false - } - if (!this.region) { - this.error = `region needs to be defined, but is not` - return false - } - if (!this.featureId) { - this.error = `featureId needs to be defined, but is not` - return false - } - return true - } - - protected async fetchReceptorData() { - this.error = null - if (!this.atlas) { - this.error = `atlas needs to be defined, but is not` - return - } - if (!this.parcellation) { - this.error = `parcellation needs to be defined, but is not` - return - } - if (!this.region) { - this.error = `region needs to be defined, but is not` - return - } - if (!this.featureId) { - this.error = `featureId needs to be defined, but is not` - return - } - const result = await this.sapi.getRegion(this.atlas["@id"], this.parcellation["@id"], this.region.name).getFeatureInstance(this.featureId, this.template["@id"]).toPromise() - if (result["@type"] !== "siibra/features/receptor") { - throw new Error(`BaseReceptor Error. Expected .type to be "siibra/features/receptor", but was "${result['@type']}"`) - } - return result - } - - abstract rerender(): void - - /** - * flag to indicate that getDataBlob() can be called. - */ - dataBlobAvailable = false - /** - * blob object observable, representing the data of the component. This allows the data to be downloaded. - */ - dataBlob$ = new BehaviorSubject<Blob>(null) - - constructor( - protected sapi: SAPI - ){ - } -} diff --git a/tmpFeatures/receptors/entry/entry.component.ts b/tmpFeatures/receptors/entry/entry.component.ts deleted file mode 100644 index 3f6a756c1..000000000 --- a/tmpFeatures/receptors/entry/entry.component.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ChangeDetectorRef, Component, OnChanges, SimpleChanges } from "@angular/core"; -import { SAPI } from "src/atlasComponents/sapi"; -import { BaseReceptor } from "../base"; - -@Component({ - selector: 'sxplr-sapiviews-features-receptor-entry', - templateUrl: `./entry.template.html`, - styleUrls: [ - `./entry.style.css` - ] -}) - -export class Entry extends BaseReceptor implements OnChanges { - selectedSymbol: string - symbolsOptions: string[] = [] - - async ngOnChanges(simpleChanges: SimpleChanges): Promise<void> { - await super.ngOnChanges(simpleChanges) - } - - loading = true - rerender(): void { - if (this.receptorData.data.receptor_symbols) { - this.loading = false - this.symbolsOptions = Object.keys(this.receptorData.data.receptor_symbols) - } - this.cdr.detectChanges() - } - constructor( - sapi: SAPI, - private cdr: ChangeDetectorRef, - ){ - super(sapi) - } - - setSelectedSymbol(select: string){ - this.selectedSymbol = select - } - - getDataBlob(): Promise<Blob> { - throw new Error(`cannot get blob of entry component`) - } -} diff --git a/tmpFeatures/receptors/entry/entry.stories.ts b/tmpFeatures/receptors/entry/entry.stories.ts deleted file mode 100644 index 63f07ee1e..000000000 --- a/tmpFeatures/receptors/entry/entry.stories.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { CommonModule, DOCUMENT } from "@angular/common" -import { HttpClientModule } from "@angular/common/http" -import { Meta, moduleMetadata, Story } from "@storybook/angular" -import { SAPI, SapiAtlasModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi" -import { getHoc1RightFeatureDetail, getHoc1RightFeatures, getHoc1Right, getHumanAtlas, getJba29, getMni152, provideDarkTheme } from "src/atlasComponents/sapi/stories.base" -import { AngularMaterialModule } from "src/sharedModules" -import { Entry } from "./entry.component" -import { ReceptorViewModule } from ".." -import { appendScriptFactory, APPEND_SCRIPT_TOKEN } from "src/util/constants" -import { Component, Output } from "@angular/core" -import { SapiRegionalFeatureReceptorModel } from "src/atlasComponents/sapi/type" - -@Component({ - selector: 'entry-wrapper-cmp', - template: ` - <sxplr-sapiviews-features-receptor-entry - [sxplr-sapiviews-features-receptor-atlas]="atlas" - [sxplr-sapiviews-features-receptor-parcellation]="parcellation" - [sxplr-sapiviews-features-receptor-template]="template" - [sxplr-sapiviews-features-receptor-region]="region" - [sxplr-sapiviews-features-receptor-featureid]="featureId" - [sxplr-sapiviews-features-receptor-data]="feature" - > - </sxplr-sapiviews-features-receptor-entry> - `, - styles: [ - ` - :host - { - display: block; - width: 20rem; - } - ` - ] -}) -class EntryWrappercls { - atlas: SapiAtlasModel - parcellation: SapiParcellationModel - template: SapiSpaceModel - region: SapiRegionModel - feature: SapiRegionalFeatureReceptorModel - featureId: string - -} - -export default { - component: EntryWrappercls, - decorators: [ - moduleMetadata({ - imports: [ - CommonModule, - HttpClientModule, - ReceptorViewModule, - AngularMaterialModule, - ], - providers: [ - SAPI, - { - provide: APPEND_SCRIPT_TOKEN, - useFactory: appendScriptFactory, - deps: [ DOCUMENT ] - }, - ...provideDarkTheme, - ], - declarations: [ - EntryWrappercls - ] - }) - ], -} as Meta - -const Template: Story<Entry> = (args: Entry, { loaded }) => { - const { atlas, parc, space, region, featureId, feature } = loaded - return ({ - props: { - ...args, - atlas: atlas, - parcellation: parc, - template: space, - region: region, - feature, - featureId, - }, - }) -} - -const loadFeat = async () => { - const atlas = await getHumanAtlas() - const parc = await getJba29() - const region = await getHoc1Right() - const space = await getMni152() - const features = await getHoc1RightFeatures() - const receptorfeat = features.find(f => f['@type'] === "siibra/features/receptor") - const feature = await getHoc1RightFeatureDetail(receptorfeat["@id"]) - return { - atlas, - parc, - space, - region, - featureId: receptorfeat["@id"], - feature - } -} - -export const Default = Template.bind({}) -Default.args = { - -} -Default.loaders = [ - async () => { - const { atlas, parc, space, region, featureId } = await loadFeat() - return { - atlas, parc, space, region, featureId - } - } -] - -export const LoadViaDirectlyInjectData = Template.bind({}) -LoadViaDirectlyInjectData.loaders = [ - async () => { - - const { feature } = await loadFeat() - return { - feature - } - } -] \ No newline at end of file diff --git a/tmpFeatures/receptors/entry/entry.style.css b/tmpFeatures/receptors/entry/entry.style.css deleted file mode 100644 index 0645dc01a..000000000 --- a/tmpFeatures/receptors/entry/entry.style.css +++ /dev/null @@ -1,4 +0,0 @@ -:host -{ - display: block; -} \ No newline at end of file diff --git a/tmpFeatures/receptors/entry/entry.template.html b/tmpFeatures/receptors/entry/entry.template.html deleted file mode 100644 index e88ce49a8..000000000 --- a/tmpFeatures/receptors/entry/entry.template.html +++ /dev/null @@ -1,80 +0,0 @@ -<mat-card> - <spinner-cmp *ngIf="loading"></spinner-cmp> - - <ng-template [ngTemplateOutlet]="downloadBtn" - [ngTemplateOutletContext]="{ - label: 'fingerprint.tsv', - filename: 'fingerprint.tsv', - receptorCmp: fp - }"> - </ng-template> - <sxplr-sapiviews-features-receptor-fingerprint - [sxplr-sapiviews-features-receptor-data]="receptorData" - (sxplr-sapiviews-features-receptor-fingerprint-receptor-selected)="setSelectedSymbol($event)" - #fp="sxplrSapiViewsFeaturesReceptorFP" - > - </sxplr-sapiviews-features-receptor-fingerprint> - - <mat-form-field appearance="fill" class="w-100"> - <mat-select [(ngModel)]="selectedSymbol"> - <mat-option value="null" disabled> - --select-- - </mat-option> - - <mat-option [value]="option" - *ngFor="let option of symbolsOptions"> - {{ option }} - </mat-option> - </mat-select> - </mat-form-field> - - <ng-template [ngIf]="selectedSymbol"> - - <ng-template [ngTemplateOutlet]="downloadBtn" - [ngTemplateOutletContext]="{ - label: 'profile.tsv', - filename: 'profile.tsv', - receptorCmp: profile - }"> - </ng-template> - <sxplr-sapiviews-features-receptor-profile - [sxplr-sapiviews-features-receptor-data]="receptorData" - [sxplr-sapiviews-features-receptor-profile-selected-symbol]="selectedSymbol" - #profile="sxplrSapiViewsFeaturesReceptorProfile"> - </sxplr-sapiviews-features-receptor-profile> - - - <ng-template [ngTemplateOutlet]="downloadBtn" - [ngTemplateOutletContext]="{ - label: 'autoradiograph.png', - filename: 'autoradiograph.png', - receptorCmp: ar - }"> - </ng-template> - <sxplr-sapiviews-features-receptor-autoradiograph - [sxplr-sapiviews-features-receptor-data]="receptorData" - [sxplr-sapiviews-features-receptor-autoradiograph-selected-symbol]="selectedSymbol" - #ar="sxplrSapiViewsFeaturesReceptorAR" - > - </sxplr-sapiviews-features-receptor-autoradiograph> - </ng-template> - -</mat-card> - - -<!-- download data button template --> -<ng-template #downloadBtn - let-label="label" - let-filename="filename" - let-receptorCmp="receptorCmp"> - <button mat-button - *ngIf="receptorCmp.dataBlobAvailable" - single-file-output - [single-file-output-blob]="receptorCmp.dataBlob$ | async" - [single-file-output-filename]="filename"> - <i class="fas fa-download"></i> - <span> - {{ label }} - </span> - </button> -</ng-template> diff --git a/tmpFeatures/receptors/fingerprint/fingerprint.component.ts b/tmpFeatures/receptors/fingerprint/fingerprint.component.ts deleted file mode 100644 index 9c77c20a1..000000000 --- a/tmpFeatures/receptors/fingerprint/fingerprint.component.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { AfterViewInit, Component, ElementRef, EventEmitter, HostListener, Inject, OnChanges, OnDestroy, Output, SimpleChanges, ViewChild } from "@angular/core"; -import { fromEvent, Observable, Subscription } from "rxjs"; -import { distinctUntilChanged, map } from "rxjs/operators"; -import { SAPI } from "src/atlasComponents/sapi"; -import { TabularFeature } from "src/atlasComponents/sapi/sxplrTypes"; -import { DARKTHEME } from "src/util/injectionTokens"; -import { BaseReceptor } from "../base"; - -/** - * kg-dataset-dumb-radar requires input to be a different shape - * once the the return signature - */ -type RequiredType = { - receptor: { - label: string - } - density: { - mean: number - sd: number - unit: string - } -} - -function transformRadar(input: TabularFeature<number>): RequiredType[]{ - const listRequired: RequiredType[] = [] - if (input.index.length !== input.data.length) { - throw new Error(`Expecting index length: '${input.index.length}' to be the same as data length : '${input.data.length}'.`) - } - const rowLength = new Set([input.data.map(row => row.length)]) - if (rowLength.size !== 1) { - throw new Error(`Expecting all row length to equal, but exists: ${JSON.stringify(Array.from(rowLength))}`) - } - input.index.forEach((label, idx) => { - listRequired.push({ - receptor: { - label - }, - density: { - mean: input.data[idx][0], - sd: input.data[idx][1], - unit: '' - } - }) - }) - return listRequired -} - -@Component({ - selector: 'sxplr-sapiviews-features-receptor-fingerprint', - templateUrl: './fingerprint.template.html', - styleUrls: [ - './fingerprint.style.css' - ], - exportAs: "sxplrSapiViewsFeaturesReceptorFP" -}) - -export class Fingerprint extends BaseReceptor implements OnChanges, AfterViewInit, OnDestroy{ - - @Output('sxplr-sapiviews-features-receptor-fingerprint-receptor-selected') - selectReceptor = new EventEmitter<string>() - - @HostListener('click') - onClick(){ - if (this.mouseOverReceptor) { - this.selectReceptor.emit(this.mouseOverReceptor) - } - } - - async ngOnChanges(simpleChanges: SimpleChanges) { - await super.ngOnChanges(simpleChanges) - } - - constructor(sapi: SAPI, private el: ElementRef, @Inject(DARKTHEME) public darktheme$: Observable<boolean>){ - super(sapi) - } - - get dumbRadarCmp(){ - return this.el?.nativeElement?.querySelector('kg-dataset-dumb-radar') - } - - private setDumbRadarPlease = false - private sub: Subscription[] = [] - private mouseOverReceptor: string - - ngOnDestroy(){ - while (this.sub.length > 0) this.sub.pop().unsubscribe() - } - - ngAfterViewInit(){ - if (this.setDumbRadarPlease) { - this.rerender() - } - - this.sub.push( - fromEvent<CustomEvent>(this.el.nativeElement, 'kg-ds-prv-regional-feature-mouseover').pipe( - map(ev => ev.detail?.data?.receptor?.label), - distinctUntilChanged(), - ).subscribe(label => { - this.mouseOverReceptor = label - }) - ) - } - - rerender(): void { - - if (!this.dumbRadarCmp) { - this.setDumbRadarPlease = true - return - } - - this.dumbRadarCmp.metaBs = this.receptorData.data.receptor_symbols - this.dumbRadarCmp.radar= transformRadar(this.receptorData.data.fingerprints) - - this.dataBlob$.next(this.getDataBlob()) - this.dataBlobAvailable = true - this.setDumbRadarPlease = false - } - - private getDataBlob(): Blob { - if (!this.receptorData?.data?.fingerprints) throw new Error(`raw data unavailable. Try again later.`) - const fingerprints = this.receptorData.data.fingerprints - const output: string[] = [] - output.push( - ["name", "mean", "std"].join("\t") - ) - for (const key in fingerprints) { - output.push( - [key, fingerprints[key].mean, fingerprints[key].std].join("\t") - ) - } - return new Blob([output.join("\n")], { type: 'text/tab-separated-values' }) - } -} diff --git a/tmpFeatures/receptors/fingerprint/fingerprint.stories.ts b/tmpFeatures/receptors/fingerprint/fingerprint.stories.ts deleted file mode 100644 index 1c3327ac1..000000000 --- a/tmpFeatures/receptors/fingerprint/fingerprint.stories.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { CommonModule, DOCUMENT } from "@angular/common" -import { HttpClientModule } from "@angular/common/http" -import { Component, EventEmitter, Output } from "@angular/core" -import { Meta, moduleMetadata, Story } from "@storybook/angular" -import { SAPI, SapiAtlasModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi" -import { getHoc1RightFeatureDetail, getHoc1RightFeatures, getHoc1Right, getHumanAtlas, getJba29, getMni152, provideDarkTheme } from "src/atlasComponents/sapi/stories.base" -import { SapiRegionalFeatureReceptorModel } from "src/atlasComponents/sapi/type" -import { AngularMaterialModule } from "src/sharedModules" -import { appendScriptFactory, APPEND_SCRIPT_TOKEN } from "src/util/constants" -import { ReceptorViewModule } from ".." - -@Component({ - selector: 'fingerprint-wrapper-cmp', - template: ` - <sxplr-sapiviews-features-receptor-fingerprint - [sxplr-sapiviews-features-receptor-atlas]="atlas" - [sxplr-sapiviews-features-receptor-parcellation]="parcellation" - [sxplr-sapiviews-features-receptor-template]="template" - [sxplr-sapiviews-features-receptor-region]="region" - [sxplr-sapiviews-features-receptor-featureid]="featureId" - [sxplr-sapiviews-features-receptor-data]="feature" - (sxplr-sapiviews-features-receptor-fingerprint-receptor-selected)="selectReceptor.emit($event)" - > - </sxplr-sapiviews-features-receptor-fingerprint> - `, - styles: [ - ` - :host - { - display: block; - width: 20rem; - height: 20rem; - } - ` - ] -}) -class FingerprintWrapperCls { - atlas: SapiAtlasModel - parcellation: SapiParcellationModel - template: SapiSpaceModel - region: SapiRegionModel - feature: SapiRegionalFeatureReceptorModel - featureId: string - - @Output() - selectReceptor = new EventEmitter() -} - -export default { - component: FingerprintWrapperCls, - decorators: [ - moduleMetadata({ - imports: [ - CommonModule, - AngularMaterialModule, - HttpClientModule, - ReceptorViewModule, - ], - providers: [ - SAPI, - { - provide: APPEND_SCRIPT_TOKEN, - useFactory: appendScriptFactory, - deps: [ DOCUMENT ] - }, - ...provideDarkTheme, - ], - declarations: [] - }) - ], -} as Meta - -const Template: Story<FingerprintWrapperCls> = (args: FingerprintWrapperCls, { loaded }) => { - const { atlas, parc, space, region, featureId, feature } = loaded - return ({ - props: { - ...args, - atlas: atlas, - parcellation: parc, - template: space, - region: region, - feature, - featureId, - }, - }) -} - -const loadFeat = async () => { - const atlas = await getHumanAtlas() - const parc = await getJba29() - const region = await getHoc1Right() - const space = await getMni152() - const features = await getHoc1RightFeatures() - const receptorfeat = features.find(f => f['@type'] === "siibra/features/receptor") - const feature = await getHoc1RightFeatureDetail(receptorfeat["@id"]) - return { - atlas, - parc, - space, - region, - featureId: receptorfeat["@id"], - feature - } -} - -export const Default = Template.bind({}) -Default.args = { - -} -Default.loaders = [ - async () => { - const { atlas, parc, space, region, featureId } = await loadFeat() - return { - atlas, parc, space, region, featureId - } - } -] - -export const LoadViaDirectlyInjectData = Template.bind({}) -LoadViaDirectlyInjectData.loaders = [ - async () => { - - const { feature } = await loadFeat() - return { - feature - } - } -] diff --git a/tmpFeatures/receptors/fingerprint/fingerprint.style.css b/tmpFeatures/receptors/fingerprint/fingerprint.style.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/tmpFeatures/receptors/fingerprint/fingerprint.template.html b/tmpFeatures/receptors/fingerprint/fingerprint.template.html deleted file mode 100644 index c315de730..000000000 --- a/tmpFeatures/receptors/fingerprint/fingerprint.template.html +++ /dev/null @@ -1,3 +0,0 @@ -<kg-dataset-dumb-radar - [attr.kg-ds-prv-darkmode]="darktheme$ | async"> -</kg-dataset-dumb-radar> \ No newline at end of file diff --git a/tmpFeatures/receptors/index.ts b/tmpFeatures/receptors/index.ts deleted file mode 100644 index 7ccaf9d94..000000000 --- a/tmpFeatures/receptors/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { Autoradiography } from "./autoradiography/autoradiography.component"; -export { Fingerprint } from "./fingerprint/fingerprint.component" -export { Profile } from "./profile/profile.component" -export { ReceptorViewModule } from "./module" diff --git a/tmpFeatures/receptors/module.ts b/tmpFeatures/receptors/module.ts deleted file mode 100644 index 34f29d7f0..000000000 --- a/tmpFeatures/receptors/module.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { CommonModule } from "@angular/common"; -import { APP_INITIALIZER, CUSTOM_ELEMENTS_SCHEMA, NgModule } from "@angular/core"; -import { FormsModule } from "@angular/forms"; -import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; -import { SpinnerModule } from "src/components/spinner"; -import { AngularMaterialModule } from "src/sharedModules"; -import { APPEND_SCRIPT_TOKEN } from "src/util/constants"; -import { ZipFilesOutputModule } from "src/zipFilesOutput/module"; -import { Autoradiography } from "./autoradiography/autoradiography.component"; -import { Entry } from "./entry/entry.component"; -import { Fingerprint } from "./fingerprint/fingerprint.component" -import { Profile } from "./profile/profile.component" - -@NgModule({ - imports: [ - CommonModule, - AngularMaterialModule, - FormsModule, - BrowserAnimationsModule, - SpinnerModule, - ZipFilesOutputModule, - ], - declarations: [ - Autoradiography, - Fingerprint, - Profile, - Entry, - ], - exports: [ - Autoradiography, - Fingerprint, - Profile, - Entry, - ], - schemas: [ - CUSTOM_ELEMENTS_SCHEMA, - ] -}) - -export class ReceptorViewModule{} diff --git a/tmpFeatures/receptors/profile/profile.component.ts b/tmpFeatures/receptors/profile/profile.component.ts deleted file mode 100644 index 864584597..000000000 --- a/tmpFeatures/receptors/profile/profile.component.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { AfterViewInit, Component, ElementRef, Inject, Input, OnChanges, SimpleChanges } from "@angular/core"; -import { Observable } from "rxjs"; -import { SAPI } from "src/atlasComponents/sapi"; -import { PARSE_TYPEDARRAY } from "src/atlasComponents/sapi/sapi.service"; -import { DARKTHEME } from "src/util/injectionTokens"; -import { BaseReceptor } from "../base"; - -@Component({ - selector: `sxplr-sapiviews-features-receptor-profile`, - templateUrl: './profile.template.html', - styleUrls: [ - './profile.style.css' - ], - exportAs: "sxplrSapiViewsFeaturesReceptorProfile" -}) - -export class Profile extends BaseReceptor implements AfterViewInit, OnChanges{ - - @Input('sxplr-sapiviews-features-receptor-profile-selected-symbol') - selectedSymbol: string - - private pleaseRender = false - dumbLineData: Record<number, number> - - constructor(sapi: SAPI, private el: ElementRef, @Inject(DARKTHEME) public darktheme$: Observable<boolean> ){ - super(sapi) - } - - async ngOnChanges(simpleChanges: SimpleChanges) { - await super.ngOnChanges(simpleChanges) - if (!this.receptorData) { - return - } - if (this.selectedSymbol) { - this.rerender() - } - } - - ngAfterViewInit(): void { - if (this.pleaseRender) { - this.rerender() - } - } - - get dumbLineCmp(){ - return this.el?.nativeElement?.querySelector('kg-dataset-dumb-line') - } - - async rerender() { - this.dataBlobAvailable = false - if (!this.dumbLineCmp) { - this.pleaseRender = true - return - } - this.pleaseRender = false - this.dumbLineData = null - - if (this.receptorData?.data?.profiles?.[this.selectedSymbol]) { - const { rawArray } = await this.sapi.processNpArrayData<PARSE_TYPEDARRAY.RAW_ARRAY>( - this.receptorData.data.profiles[this.selectedSymbol].density, - PARSE_TYPEDARRAY.RAW_ARRAY - ) - if (rawArray.length !== 1) { - this.error = `expected rawArray.length to be 1, but is ${rawArray.length} instead` - return - } - const prof = rawArray[0] - this.dumbLineData = {} - for (const idx in prof) { - this.dumbLineData[idx] = prof[idx] - } - this.dataBlob$.next(this.getDataBlob()) - this.dataBlobAvailable = true - this.dumbLineCmp.profileBs = this.dumbLineData - } - } - - private getDataBlob(): Blob { - if (!this.dumbLineData) throw new Error(`data has not been populated. Perhaps wait until render finishes?`) - const output: string[] = [] - output.push( - ["cortical depth (%)", "receptor density (fmol/mg)"].join("\t") - ) - for (const key in this.dumbLineData) { - output.push( - [key, this.dumbLineData[key]].join("\t") - ) - } - return new Blob([output.join("\n")], { type: 'text/tab-separated-values' }) - } -} diff --git a/tmpFeatures/receptors/profile/profile.stories.ts b/tmpFeatures/receptors/profile/profile.stories.ts deleted file mode 100644 index 83d309f52..000000000 --- a/tmpFeatures/receptors/profile/profile.stories.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { CommonModule, DOCUMENT } from "@angular/common" -import { HttpClientModule } from "@angular/common/http" -import { Component, NgZone, ViewChild } from "@angular/core" -import { FormsModule } from "@angular/forms" -import { BrowserAnimationsModule } from "@angular/platform-browser/animations" -import { Meta, moduleMetadata, Story } from "@storybook/angular" -import { BehaviorSubject, Subject } from "rxjs" -import { SAPI, SapiAtlasModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi" -import { addAddonEventListener, getHoc1RightFeatureDetail, getHoc1RightFeatures, getHoc1Right, getHumanAtlas, getJba29, getMni152, provideDarkTheme } from "src/atlasComponents/sapi/stories.base" -import { SapiRegionalFeatureReceptorModel } from "src/atlasComponents/sapi/type" -import { AngularMaterialModule } from "src/sharedModules" -import { appendScriptFactory, APPEND_SCRIPT_TOKEN } from "src/util/constants" -import { DARKTHEME } from "src/util/injectionTokens" -import { ReceptorViewModule } from ".." -import { Profile } from "./profile.component" - -@Component({ - selector: 'autoradiograph-wrapper-cmp', - template: ` - <mat-form-field appearance="fill"> - <mat-select [(ngModel)]="selectedSymbol"> - <mat-option value="" disabled> - --select-- - </mat-option> - - <mat-option [value]="option" - *ngFor="let option of options"> - {{ option }} - </mat-option> - </mat-select> - </mat-form-field> - <sxplr-sapiviews-features-receptor-profile - class="d-inline-block w-100 h-100" - [sxplr-sapiviews-features-receptor-atlas]="atlas" - [sxplr-sapiviews-features-receptor-parcellation]="parcellation" - [sxplr-sapiviews-features-receptor-template]="template" - [sxplr-sapiviews-features-receptor-region]="region" - [sxplr-sapiviews-features-receptor-featureid]="featureId" - [sxplr-sapiviews-features-receptor-data]="feature" - [sxplr-sapiviews-features-receptor-profile-selected-symbol]="selectedSymbol" - > - </sxplr-sapiviews-features-receptor-profile> - `, - styles: [ - ` - :host - { - display: block; - max-width: 24rem; - max-height: 24rem; - } - ` - ] -}) -class ProfileWrapperCls { - atlas: SapiAtlasModel - parcellation: SapiParcellationModel - template: SapiSpaceModel - region: SapiRegionModel - - feature: SapiRegionalFeatureReceptorModel - featureId: string - - @ViewChild(Profile) - profile: Profile - - selectedSymbol: string - - get options(){ - return Object.keys(this.feature?.data?.profiles || this.profile?.receptorData?.data?.profiles || {}) - } -} - -export default { - component: ProfileWrapperCls, - decorators: [ - moduleMetadata({ - imports: [ - CommonModule, - AngularMaterialModule, - HttpClientModule, - BrowserAnimationsModule, - FormsModule, - ReceptorViewModule, - ], - providers: [ - SAPI, - { - provide: APPEND_SCRIPT_TOKEN, - useFactory: appendScriptFactory, - deps: [ DOCUMENT ] - }, - ...provideDarkTheme, - ], - declarations: [] - }) - ], -} as Meta - -const Template: Story<ProfileWrapperCls> = (args: ProfileWrapperCls, { loaded }) => { - const { atlas, parc, space, region, featureId, feature } = loaded - return ({ - props: { - ...args, - atlas: atlas, - parcellation: parc, - template: space, - region: region, - feature, - featureId, - }, - }) -} - -const loadFeat = async () => { - const atlas = await getHumanAtlas() - const parc = await getJba29() - const region = await getHoc1Right() - const space = await getMni152() - const features = await getHoc1RightFeatures() - const receptorfeat = features.find(f => f['@type'] === "siibra/features/receptor") - const feature = await getHoc1RightFeatureDetail(receptorfeat["@id"]) - return { - atlas, - parc, - space, - region, - featureId: receptorfeat["@id"], - feature - } -} - -export const Default = Template.bind({}) -Default.args = { - -} -Default.loaders = [ - async () => { - const { atlas, parc, space, region, featureId } = await loadFeat() - return { - atlas, parc, space, region, featureId - } - } -] - -export const LoadViaDirectlyInjectData = Template.bind({}) -LoadViaDirectlyInjectData.loaders = [ - async () => { - - const { feature } = await loadFeat() - return { - feature - } - } -] diff --git a/tmpFeatures/receptors/profile/profile.style.css b/tmpFeatures/receptors/profile/profile.style.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/tmpFeatures/receptors/profile/profile.template.html b/tmpFeatures/receptors/profile/profile.template.html deleted file mode 100644 index 182db6578..000000000 --- a/tmpFeatures/receptors/profile/profile.template.html +++ /dev/null @@ -1,3 +0,0 @@ -<kg-dataset-dumb-line - [attr.kg-ds-prv-darkmode]="darktheme$ | async"> -</kg-dataset-dumb-line> \ No newline at end of file diff --git a/tmpFeatures/voi/index.ts b/tmpFeatures/voi/index.ts deleted file mode 100644 index 55b2fbc01..000000000 --- a/tmpFeatures/voi/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { SapiViewsFeaturesVoiModule } from "./module" -export { SapiViewsFeaturesVoiQuery } from "./voiQuery.directive" diff --git a/tmpFeatures/voi/module.ts b/tmpFeatures/voi/module.ts deleted file mode 100644 index e9817aaca..000000000 --- a/tmpFeatures/voi/module.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { CommonModule } from "@angular/common"; -import { NgModule } from "@angular/core"; -import { SAPIModule } from "src/atlasComponents/sapi/module"; -import { SapiViewsFeaturesVoiQuery } from "./voiQuery.directive"; - -@NgModule({ - imports: [ - CommonModule, - SAPIModule, - ], - declarations: [ - SapiViewsFeaturesVoiQuery, - ], - exports: [ - SapiViewsFeaturesVoiQuery - ] -}) - -export class SapiViewsFeaturesVoiModule{} diff --git a/tmpFeatures/voi/voiQuery.directive.ts b/tmpFeatures/voi/voiQuery.directive.ts deleted file mode 100644 index a9eaab487..000000000 --- a/tmpFeatures/voi/voiQuery.directive.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { Directive, EventEmitter, Inject, Input, OnChanges, OnDestroy, Optional, Output, SimpleChanges } from "@angular/core"; -import { interval, merge, Observable, of, Subject, Subscription } from "rxjs"; -import { debounce, debounceTime, distinctUntilChanged, filter, pairwise, shareReplay, startWith, switchMap, take, tap } from "rxjs/operators"; -import { AnnotationLayer, TNgAnnotationPoint, TNgAnnotationAABBox } from "src/atlasComponents/annotations"; -import { SAPI } from "src/atlasComponents/sapi/sapi.service"; -import { BoundingBox, SxplrAtlas, SxplrTemplate, VoiFeature } from "src/atlasComponents/sapi/sxplrTypes"; - -import { ClickInterceptor, CLICK_INTERCEPTOR_INJECTOR } from "src/util"; -import { arrayEqual } from "src/util/array"; - -@Directive({ - selector: '[sxplr-sapiviews-features-voi-query]', - exportAs: 'sxplrSapiViewsFeaturesVoiQuery' -}) - -export class SapiViewsFeaturesVoiQuery implements OnChanges, OnDestroy{ - - static VOI_LAYER_NAME = 'voi-annotation-layer' - static VOI_ANNOTATION_COLOR = "#ffff00" - private voiQuerySpec = new Subject<{ - atlas: SxplrAtlas - space: SxplrTemplate - bbox: BoundingBox - }>() - - private canFetchVoi(){ - return !!this.atlas && !!this.space && !!this.bbox - } - - @Input('sxplr-sapiviews-features-voi-query-atlas') - atlas: SxplrAtlas - - @Input('sxplr-sapiviews-features-voi-query-space') - space: SxplrTemplate - - @Input('sxplr-sapiviews-features-voi-query-bbox') - bbox: BoundingBox - - @Output('sxplr-sapiviews-features-voi-query-onhover') - onhover = new EventEmitter<VoiFeature>() - - @Output('sxplr-sapiviews-features-voi-query-onclick') - onclick = new EventEmitter<VoiFeature>() - - public busy$ = new EventEmitter<boolean>() - public features$: Observable<VoiFeature[]> = this.voiQuerySpec.pipe( - debounceTime(160), - tap(() => this.busy$.emit(true)), - switchMap(({ atlas, bbox, space }) => { - if (!this.canFetchVoi()) { - return of([]) - } - return merge( - of([]), - this.sapi.getVoiFeatures(bbox) - ) - }), - startWith([]), - shareReplay(1) - ) - - private hoveredFeat: VoiFeature - private onDestroyCb: (() => void)[] = [] - private subscription: Subscription[] = [] - ngOnChanges(simpleChanges: SimpleChanges): void { - if (simpleChanges.space) { - this.voiBBoxSvc = null - } - const { - atlas, - space, - bbox - } = this - this.voiQuerySpec.next({ atlas, space, bbox }) - } - ngOnDestroy(): void { - if (this.voiBBoxSvc) this.voiBBoxSvc.dispose() - while (this.subscription.length > 0) this.subscription.pop().unsubscribe() - while (this.voiSubs.length > 0) this.voiSubs.pop().unsubscribe() - while(this.onDestroyCb.length > 0) this.onDestroyCb.pop()() - } - - handleOnHoverFeature({ id }: { id?: string }){ - const ann = this.annotationIdToFeature.get(id) - this.hoveredFeat = ann - this.onhover.emit(ann) - } - - private voiSubs: Subscription[] = [] - private _voiBBoxSvc: AnnotationLayer - get voiBBoxSvc(): AnnotationLayer { - if (this._voiBBoxSvc) return this._voiBBoxSvc - try { - const layer = AnnotationLayer.Get( - SapiViewsFeaturesVoiQuery.VOI_LAYER_NAME, - SapiViewsFeaturesVoiQuery.VOI_ANNOTATION_COLOR - ) - this._voiBBoxSvc = layer - this.voiSubs.push( - layer.onHover.subscribe(val => this.handleOnHoverFeature(val || {})) - ) - return layer - } catch (e) { - return null - } - } - set voiBBoxSvc(val) { - if (!!val) { - throw new Error(`cannot set voiBBoxSvc directly`) - } - while (this.voiSubs.length > 0) this.voiSubs.pop().unsubscribe() - this._voiBBoxSvc && this._voiBBoxSvc.dispose() - this._voiBBoxSvc = null - } - - constructor( - private sapi: SAPI, - @Optional() @Inject(CLICK_INTERCEPTOR_INJECTOR) clickInterceptor: ClickInterceptor, - ){ - const handle = () => { - if (!this.hoveredFeat) return true - this.onclick.emit(this.hoveredFeat) - return false - } - this.onDestroyCb.push( - () => clickInterceptor.deregister(handle) - ) - clickInterceptor.register(handle) - this.subscription.push( - this.features$.pipe( - startWith([] as VoiFeature[]), - distinctUntilChanged(arrayEqual((o, n) => o["@id"] === n["@id"])), - pairwise(), - debounce(() => - interval(16).pipe( - filter(() => !!this.voiBBoxSvc), - take(1), - ) - ), - ).subscribe(([ prev, curr ]) => { - for (const v of prev) { - const box = this.pointsToAABB(v.bbox.maxpoint, v.bbox.minpoint) - const point = this.pointToPoint(v.bbox.center) - this.annotationIdToFeature.delete(box.id) - this.annotationIdToFeature.delete(point.id) - if (!this.voiBBoxSvc) continue - for (const ann of [box, point]) { - this.voiBBoxSvc.removeAnnotation({ - id: ann.id - }) - } - } - for (const v of curr) { - const box = this.pointsToAABB(v.bbox.maxpoint, v.bbox.minpoint) - const point = this.pointToPoint(v.bbox.center) - this.annotationIdToFeature.set(box.id, v) - this.annotationIdToFeature.set(point.id, v) - if (!this.voiBBoxSvc) { - throw new Error(`annotation is expected to be added, but annotation layer cannot be instantiated.`) - } - for (const ann of [box, point]) { - this.voiBBoxSvc.updateAnnotation(ann) - } - } - if (this.voiBBoxSvc) this.voiBBoxSvc.setVisible(true) - }) - ) - } - - private annotationIdToFeature = new Map<string, VoiFeature>() - - private pointsToAABB(pointA: [number, number, number], pointB: [number, number, number]): TNgAnnotationAABBox{ - return { - id: `${SapiViewsFeaturesVoiQuery.VOI_LAYER_NAME}:${pointA["@id"]}:${pointB["@id"]}`, - pointA: pointA.map(v => v * 1e6) as [number, number, number], - pointB: pointB.map(v => v * 1e6) as [number, number, number], - type: "aabbox" - } - } - private pointToPoint(point: [number, number, number]): TNgAnnotationPoint { - return { - id: `${SapiViewsFeaturesVoiQuery.VOI_LAYER_NAME}:${JSON.stringify(point)}}`, - point: point.map(v => v * 1e6) as [number, number, number], - type: "point" - } - } -} -- GitLab