Skip to content

Commit

Permalink
Option to skip QC steps, e.g., when processing filtered datasets. (#130)
Browse files Browse the repository at this point in the history
* Added UI elements for skipping the RNA and ADT QC steps.

* Add no-QC parameters to the defaults.

* fix: bug when QC results are null

* on reanalysis, if qc is skipped, remove qc plots from the interface

* bump pkg version

Co-authored-by: Jayaram Kancherla <[email protected]>
  • Loading branch information
LTLA and jkanche authored Jul 23, 2022
1 parent 2437d4b commit 65dc6b0
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 78 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"bakana": "~0.4.0",
"bakana": "^0.4.0",
"d3": "^7.1.1",
"epiviz.gl": "^1.0.2",
"epiviz.scatter.gl": "^0.0.5",
Expand Down
31 changes: 18 additions & 13 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,21 +472,26 @@ const App = () => {
} else if (payload.type === "quality_control_DATA") {
const { resp } = payload;

var ranges = {}, data = resp["data"], all = {};

for (const [group, gvals] of Object.entries(data)) {
for (const [key, val] of Object.entries(gvals)) {
if (!all[key]) all[key] = [Infinity, -Infinity];
let [min, max] = getMinMax(val);
if (min < all[key][0]) all[key][0] = min;
if (max > all[key][1]) all[key][1] = max;
if (!resp) {
setQcData(null);
setShowQCLoader(false);
} else {
var ranges = {}, data = resp["data"], all = {};

for (const [group, gvals] of Object.entries(data)) {
for (const [key, val] of Object.entries(gvals)) {
if (!all[key]) all[key] = [Infinity, -Infinity];
let [min, max] = getMinMax(val);
if (min < all[key][0]) all[key][0] = min;
if (max > all[key][1]) all[key][1] = max;
}
ranges[group] = all;
}
ranges[group] = all;

resp["ranges"] = ranges;
setQcData(resp);
setShowQCLoader(false);
}

resp["ranges"] = ranges;
setQcData(resp);
setShowQCLoader(false);
} else if (payload.type === "adt_quality_control_DATA") {
const { resp } = payload;

Expand Down
158 changes: 98 additions & 60 deletions src/components/Analysis/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,12 @@ const AnalysisDialog = ({
Prefix to use to identify the mitochondrial genes from the feature annotation.
Only used if we choose to not use the default mitochondrial list.
</p>
<p>
<strong>Skip</strong>:
Skip all quality control on the RNA count matrix.
This is occasionally desirable if the input data has already been subjected to QC (e.g., as part of a published paper),
in which case no further filtering should be applied.
</p>
</Callout>
}
{showStepHelper === 3 &&
Expand Down Expand Up @@ -601,6 +607,12 @@ const AnalysisDialog = ({
Prefix to use to identify features in the dataset that are isotype controls.
This is not case-sensitive.
</p>
<p>
<strong>Skip</strong>:
Skip all quality control on the ADT count matrix.
This is occasionally desirable if the input data has already been subjected to QC (e.g., as part of a published paper),
in which case no further filtering should be applied.
</p>
</Callout>
}
{showStepHelper === 12 &&
Expand Down Expand Up @@ -679,38 +691,51 @@ const AnalysisDialog = ({
<Text className="text-100">
<span className={showStepHelper == 2 ? 'row-tooltip row-tooltip-highlight' : 'row-tooltip'}
onMouseEnter={() => setShowStepHelper(2)}>
Number of MADs
</span>
</Text>
<NumericInput
placeholder="3" value={tmpInputParams["qc"]["qc-nmads"]}
onValueChange={(nval, val) => { setTmpInputParams({ ...tmpInputParams, "qc": { ...tmpInputParams["qc"], "qc-nmads": nval } }) }} />
</Label>
<Label className="row-input">
<Text className="text-100">
<span className={showStepHelper == 2 ? 'row-tooltip row-tooltip-highlight' : 'row-tooltip'}
onMouseEnter={() => setShowStepHelper(2)}>
Use default mitochondrial list ?
Skip
</span>
</Text>
<Switch style={{ marginTop: '10px' }} large={true} checked={tmpInputParams["qc"]["qc-usemitodefault"]}
<Switch style={{ marginTop: '10px' }} large={true} checked={tmpInputParams["qc"]["skip"]}
innerLabelChecked="yes" innerLabel="no"
onChange={(e) => { setTmpInputParams({ ...tmpInputParams, "qc": { ...tmpInputParams["qc"], "qc-usemitodefault": e.target.checked } }) }} />
onChange={(e) => { setTmpInputParams({ ...tmpInputParams, "qc": { ...tmpInputParams["qc"], "skip": e.target.checked } }) }} />
</Label>
{!tmpInputParams["qc"]["qc-usemitodefault"] && <Label className="row-input">
<Text className="text-100">
<span className={showStepHelper == 2 ? 'row-tooltip row-tooltip-highlight' : 'row-tooltip'}
onMouseEnter={() => setShowStepHelper(2)}>
Mitochondrial gene prefix
</span>
</Text>
<InputGroup
leftIcon="filter"
onChange={(nval, val) => { setTmpInputParams({ ...tmpInputParams, "qc": { ...tmpInputParams["qc"], "qc-mito": nval?.target?.value } }) }}
placeholder="mt-"
value={tmpInputParams["qc"]["qc-mito"]}
/>
</Label>}
{ tmpInputParams?.qc?.skip !== true && <>
<Label className="row-input">
<Text className="text-100">
<span className={showStepHelper == 2 ? 'row-tooltip row-tooltip-highlight' : 'row-tooltip'}
onMouseEnter={() => setShowStepHelper(2)}>
Number of MADs
</span>
</Text>
<NumericInput
placeholder="3" value={tmpInputParams["qc"]["qc-nmads"]}
onValueChange={(nval, val) => { setTmpInputParams({ ...tmpInputParams, "qc": { ...tmpInputParams["qc"], "qc-nmads": nval } }) }} />
</Label>
<Label className="row-input">
<Text className="text-100">
<span className={showStepHelper == 2 ? 'row-tooltip row-tooltip-highlight' : 'row-tooltip'}
onMouseEnter={() => setShowStepHelper(2)}>
Use default mitochondrial list ?
</span>
</Text>
<Switch style={{ marginTop: '10px' }} large={true} checked={tmpInputParams["qc"]["qc-usemitodefault"]}
innerLabelChecked="yes" innerLabel="no"
onChange={(e) => { setTmpInputParams({ ...tmpInputParams, "qc": { ...tmpInputParams["qc"], "qc-usemitodefault": e.target.checked } }) }} />
</Label>
{!tmpInputParams["qc"]["qc-usemitodefault"] && <Label className="row-input">
<Text className="text-100">
<span className={showStepHelper == 2 ? 'row-tooltip row-tooltip-highlight' : 'row-tooltip'}
onMouseEnter={() => setShowStepHelper(2)}>
Mitochondrial gene prefix
</span>
</Text>
<InputGroup
leftIcon="filter"
onChange={(nval, val) => { setTmpInputParams({ ...tmpInputParams, "qc": { ...tmpInputParams["qc"], "qc-mito": nval?.target?.value } }) }}
placeholder="mt-"
value={tmpInputParams["qc"]["qc-mito"]}
/>
</Label>}
</>}
</div>
</div>
</div>
Expand Down Expand Up @@ -1238,41 +1263,54 @@ const AnalysisDialog = ({
<Text className="text-100">
<span className={showStepHelper == 11 ? 'row-tooltip row-tooltip-highlight' : 'row-tooltip'}
onMouseEnter={() => setShowStepHelper(11)}>
Number of MADs
</span>
</Text>
<NumericInput
placeholder="3" value={tmpInputParams["adt_qualitycontrol"]["nmads"]}
onValueChange={(nval, val) => { setTmpInputParams({ ...tmpInputParams, "adt_qualitycontrol": { ...tmpInputParams["adt_qualitycontrol"], "nmads": nval } }) }} />
</Label>
<Label className="row-input">
<Text className="text-100">
<span className={showStepHelper == 11 ? 'row-tooltip row-tooltip-highlight' : 'row-tooltip'}
onMouseEnter={() => setShowStepHelper(11)}>
Minimum Detected Drop
</span>
</Text>
<NumericInput
placeholder="0.1"
stepSize={0.01}
minorStepSize={0.01}
value={tmpInputParams["adt_qualitycontrol"]["min_detected_drop"]}
onValueChange={(nval, val) => { setTmpInputParams({ ...tmpInputParams, "adt_qualitycontrol": { ...tmpInputParams["adt_qualitycontrol"], "min_detected_drop": val } }) }} />
</Label>
<Label className="row-input">
<Text className="text-100">
<span className={showStepHelper == 11 ? 'row-tooltip row-tooltip-highlight' : 'row-tooltip'}
onMouseEnter={() => setShowStepHelper(11)}>
Prefix for isotype controls.
Skip
</span>
</Text>
<InputGroup
leftIcon="filter"
onChange={(nval, val) => { setTmpInputParams({ ...tmpInputParams, "adt_qualitycontrol": { ...tmpInputParams["adt_qualitycontrol"], "igg_prefix": nval?.target?.value } }) }}
placeholder="IgG"
value={tmpInputParams["adt_qualitycontrol"]["igg_prefix"]}
/>
<Switch style={{ marginTop: '10px' }} large={true} checked={tmpInputParams["adt_qualitycontrol"]["skip"]}
innerLabelChecked="yes" innerLabel="no"
onChange={(e) => { setTmpInputParams({ ...tmpInputParams, "adt_qualitycontrol": { ...tmpInputParams["adt_qualitycontrol"], "skip": e.target.checked } }) }} />
</Label>
{ tmpInputParams?.adt_qualitycontrol?.skip !== true && <>
<Label className="row-input">
<Text className="text-100">
<span className={showStepHelper == 11 ? 'row-tooltip row-tooltip-highlight' : 'row-tooltip'}
onMouseEnter={() => setShowStepHelper(11)}>
Number of MADs
</span>
</Text>
<NumericInput
placeholder="3" value={tmpInputParams["adt_qualitycontrol"]["nmads"]}
onValueChange={(nval, val) => { setTmpInputParams({ ...tmpInputParams, "adt_qualitycontrol": { ...tmpInputParams["adt_qualitycontrol"], "nmads": nval } }) }} />
</Label>
<Label className="row-input">
<Text className="text-100">
<span className={showStepHelper == 11 ? 'row-tooltip row-tooltip-highlight' : 'row-tooltip'}
onMouseEnter={() => setShowStepHelper(11)}>
Minimum Detected Drop
</span>
</Text>
<NumericInput
placeholder="0.1"
stepSize={0.01}
minorStepSize={0.01}
value={tmpInputParams["adt_qualitycontrol"]["min_detected_drop"]}
onValueChange={(nval, val) => { setTmpInputParams({ ...tmpInputParams, "adt_qualitycontrol": { ...tmpInputParams["adt_qualitycontrol"], "min_detected_drop": val } }) }} />
</Label>
<Label className="row-input">
<Text className="text-100">
<span className={showStepHelper == 11 ? 'row-tooltip row-tooltip-highlight' : 'row-tooltip'}
onMouseEnter={() => setShowStepHelper(11)}>
Prefix for isotype controls.
</span>
</Text>
<InputGroup
leftIcon="filter"
onChange={(nval, val) => { setTmpInputParams({ ...tmpInputParams, "adt_qualitycontrol": { ...tmpInputParams["adt_qualitycontrol"], "igg_prefix": nval?.target?.value } }) }}
placeholder="IgG"
value={tmpInputParams["adt_qualitycontrol"]["igg_prefix"]}
/>
</Label>
</>}
</div>
</div>
</div>
Expand Down
13 changes: 13 additions & 0 deletions src/components/Gallery/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const Gallery = (props) => {
const [items, setItems] = useState([]);
const [itemContent, setItemContent] = useState({});
const { datasetName, genesInfo, geneColSel } = useContext(AppContext);
const [qcids, setQCids] = useState([]);

function get_image_title(data) {
let text = ` ${data?.config?.embedding} `;
Expand Down Expand Up @@ -92,6 +93,7 @@ const Gallery = (props) => {
let tmpItemContent = { ...itemContent };

if (props?.qcData && isObject(props?.qcData?.data)) {
let tqcid = [...qcids];
Object.keys(props?.qcData?.data).map((x, qci) => {
let tqc = {
data: props?.qcData?.data[x],
Expand All @@ -101,6 +103,7 @@ const Gallery = (props) => {

if (!tmpItems.includes(`${1 + qci}`)) {
tmpItems.push(`${1 + qci}`);
tqcid.push(`${1 + qci}`);
}

let title = `QC for batch: ${x}`;
Expand All @@ -124,6 +127,16 @@ const Gallery = (props) => {
content: <QCPlotMgr title={x} data={tqc} />,
};
});

setQCids(tqcid);
} else {
if (qcids && qcids.length > 0) {
qcids.map(x => {
tmpItems.splice(tmpItems.indexOf(x), 1);
delete tmpItemContent[`${x}`];
});
setQCids([]);
}
}

if (Object.keys(props?.pcaVarExp).length > 0) {
Expand Down
6 changes: 4 additions & 2 deletions src/context/AppContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ const AppContextProvider = ({ children }) => {
qc: {
"qc-nmads": 3,
"qc-usemitodefault": true,
"qc-mito": "mt-"
"qc-mito": "mt-",
"skip": false
},
fSelection: {
"fsel-span": 0.3
Expand Down Expand Up @@ -56,7 +57,8 @@ const AppContextProvider = ({ children }) => {
adt_qualitycontrol: {
igg_prefix: "IgG",
nmads: 3,
min_detected_drop: 0.1
min_detected_drop: 0.1,
skip: false
},
adt_pca: {
num_pcs: 20,
Expand Down
6 changes: 4 additions & 2 deletions src/workers/translate.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ const mappings = {
quality_control: {
use_mito_default: [ "qc", "qc-usemitodefault" ],
mito_prefix: [ "qc", "qc-mito" ],
nmads: [ "qc", "qc-nmads" ]
nmads: [ "qc", "qc-nmads" ],
skip: [ "qc", "skip" ]
},
adt_quality_control: {
nmads: [ "adt_qualitycontrol", "nmads" ],
min_detected_drop: [ "adt_qualitycontrol", "min_detected_drop" ],
igg_prefix: [ "adt_qualitycontrol", "igg_prefix" ]
igg_prefix: [ "adt_qualitycontrol", "igg_prefix" ],
skip: [ "adt_qualitycontrol", "skip" ]
},
adt_normalization: {
num_pcs: [ "adt_normalization", "num_pcs" ],
Expand Down

0 comments on commit 65dc6b0

Please sign in to comment.