-
Notifications
You must be signed in to change notification settings - Fork 0
Add PCA (dimensionality reduction) compute and plot #1504
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
f423da2
f844bbb
eef9f72
e0e7c8e
4451729
730c393
f4a0b2f
5dad702
1a0ddf8
e079883
6082e20
4a31e24
749db05
931bfe8
9558316
ac96f08
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,173 @@ | ||
| import { useFindEntityAndVariableCollection } from '../../..'; | ||
| import { VariableCollectionDescriptor } from '../../../types/variable'; | ||
| import { scatterplotVisualization } from '../../visualizations/implementations/ScatterplotVisualization'; | ||
| import { ComputationConfigProps, ComputationPlugin } from '../Types'; | ||
| import { partial } from 'lodash'; | ||
| import { | ||
| useConfigChangeHandler, | ||
| assertComputationWithConfig, | ||
| isNotAbsoluteAbundanceVariableCollection, | ||
| partialToCompleteCodec, | ||
| } from '../Utils'; | ||
| import * as t from 'io-ts'; | ||
| import { Computation } from '../../../types/visualization'; | ||
| import SingleSelect from '@veupathdb/coreui/lib/components/inputs/SingleSelect'; | ||
asizemore marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| import { useMemo } from 'react'; | ||
asizemore marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| import ScatterBetadivSVG from '../../visualizations/implementations/selectorIcons/ScatterBetadivSVG'; | ||
| import { ComputationStepContainer } from '../ComputationStepContainer'; | ||
| import './Plugins.scss'; | ||
| import { makeClassNameHelper } from '@veupathdb/wdk-client/lib/Utils/ComponentUtils'; | ||
| import { VariableCollectionSingleSelect } from '../../variableSelectors/VariableCollectionSingleSelect'; | ||
| import { IsEnabledInPickerParams } from '../../visualizations/VisualizationTypes'; | ||
| import { entityTreeToArray } from '../../../utils/study-metadata'; | ||
| import { InputSpec } from '../../visualizations/InputVariables'; | ||
asizemore marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| const cx = makeClassNameHelper('AppStepConfigurationContainer'); | ||
|
|
||
| export type DimensionalityReductionConfig = t.TypeOf< | ||
| typeof DimensionalityReductionConfig | ||
| >; | ||
| // eslint-disable-next-line @typescript-eslint/no-redeclare | ||
| export const DimensionalityReductionConfig = t.partial({ | ||
| collectionVariable: VariableCollectionDescriptor, | ||
| }); | ||
|
|
||
| const CompleteDimensionalityReductionConfig = partialToCompleteCodec( | ||
| DimensionalityReductionConfig | ||
| ); | ||
|
|
||
| export const plugin: ComputationPlugin = { | ||
| configurationComponent: DimensionalityReductionConfiguration, | ||
| configurationDescriptionComponent: | ||
| DimensionalityReductionConfigDescriptionComponent, | ||
| createDefaultConfiguration: () => ({}), | ||
| isConfigurationComplete: CompleteDimensionalityReductionConfig.is, | ||
| visualizationPlugins: { | ||
| scatterplot: scatterplotVisualization | ||
| .withOptions({ | ||
| getComputedXAxisDetails(config) { | ||
| if ( | ||
| DimensionalityReductionConfig.is(config) && | ||
| config.collectionVariable | ||
| ) { | ||
| return { | ||
| entityId: config.collectionVariable.entityId, | ||
| placeholderDisplayName: 'PCA Axis 1', | ||
| variableId: 'PC1', | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So we just "know" that "PC1" is a valid
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, for right now we just "know", and yep you're right it's defined in the backend. The differential expression function in veupathutils returns multiple PCs and you can even tell it how many to return. I had started to implement support for choosing PCs but then left it alone because it felt like it was making the initial deliverable too big. |
||
| }; | ||
| } | ||
| }, | ||
| getComputedYAxisDetails(config) { | ||
| if ( | ||
| DimensionalityReductionConfig.is(config) && | ||
| config.collectionVariable | ||
| ) { | ||
| return { | ||
| entityId: config.collectionVariable.entityId, | ||
| placeholderDisplayName: 'PCA Axis 2', | ||
| variableId: 'PC2', | ||
| }; | ||
| } | ||
| }, | ||
| hideShowMissingnessToggle: true, | ||
| hideTrendlines: true, | ||
| hideFacetInputs: true, | ||
| hideLogScale: true, | ||
| returnPointIds: false, | ||
| sendComputedVariablesInRequest: true, | ||
| }) | ||
| .withSelectorIcon(ScatterBetadivSVG), | ||
| }, | ||
| isEnabledInPicker: isEnabledInPicker, | ||
| studyRequirements: | ||
| 'These visualizations are only available for studies with compatible assay data.', | ||
| }; | ||
|
|
||
| function DimensionalityReductionConfigDescriptionComponent({ | ||
| computation, | ||
| }: { | ||
| computation: Computation; | ||
| }) { | ||
| const findEntityAndVariableCollection = useFindEntityAndVariableCollection(); | ||
| assertComputationWithConfig(computation, DimensionalityReductionConfig); | ||
| const { configuration } = computation.descriptor; | ||
| const collectionVariable = | ||
| 'collectionVariable' in configuration | ||
| ? configuration.collectionVariable | ||
| : undefined; | ||
| const updatedCollectionVariable = | ||
| findEntityAndVariableCollection(collectionVariable); | ||
|
|
||
| return ( | ||
| <div className="ConfigDescriptionContainer"> | ||
| <h4> | ||
| Data:{' '} | ||
| <span> | ||
| {updatedCollectionVariable ? ( | ||
| `${updatedCollectionVariable.entity.displayName} > ${updatedCollectionVariable.variableCollection.displayName}` | ||
| ) : ( | ||
| <i>Not selected</i> | ||
| )} | ||
| </span> | ||
| </h4> | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| export function DimensionalityReductionConfiguration( | ||
| props: ComputationConfigProps | ||
| ) { | ||
| const { | ||
| computationAppOverview, | ||
| computation, | ||
| analysisState, | ||
| visualizationId, | ||
| } = props; | ||
| assertComputationWithConfig(computation, DimensionalityReductionConfig); | ||
| const configuration = computation.descriptor.configuration; | ||
|
|
||
| const changeConfigHandler = useConfigChangeHandler( | ||
| analysisState, | ||
| computation, | ||
| visualizationId | ||
| ); | ||
|
|
||
| return ( | ||
| <ComputationStepContainer | ||
| computationStepInfo={{ | ||
| stepNumber: 1, | ||
| stepTitle: `Configure ${computationAppOverview.displayName}`, | ||
| }} | ||
| > | ||
| <div className={cx()}> | ||
| <div className={cx('-InputContainer')}> | ||
| <span>Data</span> | ||
| <VariableCollectionSingleSelect | ||
| value={configuration.collectionVariable} | ||
| onSelect={(value) => { | ||
| if (typeof value === 'string') return; | ||
| changeConfigHandler('collectionVariable', value); | ||
| }} | ||
| collectionPredicate={isNotAbsoluteAbundanceVariableCollection} | ||
| /> | ||
| </div> | ||
| </div> | ||
| </ComputationStepContainer> | ||
| ); | ||
| } | ||
|
|
||
| // Beta div's only requirement of the study is that it contains | ||
asizemore marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // at least one collection | ||
| function isEnabledInPicker({ | ||
| studyMetadata, | ||
| }: IsEnabledInPickerParams): boolean { | ||
| if (!studyMetadata) return false; | ||
| const entities = entityTreeToArray(studyMetadata.rootEntity); | ||
|
|
||
| // Ensure there are collections in this study. Otherwise, disable app | ||
| const studyHasCollections = entities.some( | ||
| (entity) => !!entity.collections?.length | ||
| ); | ||
|
|
||
| return studyHasCollections; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.