Commit daa25c4d authored by Kiraa Corsac's avatar Kiraa Corsac
Browse files

proteins.js; use async computations api

parent 55ea8e7b
Loading
Loading
Loading
Loading
Loading
+143 −105
Original line number Diff line number Diff line
@@ -16,6 +16,16 @@ function roundToTwo(num) {
    return +(Math.round(num + "e+2") + "e-2");
}

async function wait_for_computation_async(api, route, pid, polling_time) {
    let finished = null
    let status_response = null
    while (finished != true) {
        status_response = await api.get(`/${route}/computation_status/${pid}`)
        await new Promise(resolve => setTimeout(resolve, polling_time));
        finished = status_response.data.finished;
    }
    return status_response
}


export default {
@@ -532,55 +542,97 @@ export default {
            return request
        },

        addCorrelatedBFactors(context, { protein, bfactors, files }) {
            //TODO: Fix race condition on server regarding (probably) writing to same files,
            // causing correlate_bfactors to crash.
            // As a hotfix, the flexibility computation is called sequentially instead of paraller.   
        async addCorrelatedBFactors(context, { protein, bfactors, files }) {
            context.commit("renewSegmentation", { proteinName: protein.name });
            let encodedFiles = null;
            let flexibility = Promise.all(files.map(f => toBase64(f)))
                .then((encodedFilesResolution) => {
                    encodedFiles = encodedFilesResolution;
                })
                .then(() => context.getters.getApi.post(`/bfactors`, {
            let flexibility_files = await Promise.all(files.map(f => toBase64(f)));
            let flexibility_computation = Promise.all(
                [
                    (() => {
                        let residue_proimise = context.getters.getApi.post(`/flexibility/start_computation`, {
                            pdb: protein.name,
                            chain: protein.chain,
                            types: bfactors,
                            segmentation: null,
                    file: encodedFiles,
                            file: flexibility_files,
                            crosscorelation: false,
                            bfactor_aggregation_type: 'residue',
                })).then(bfactors => {
                    context.commit("addAcidsFlexibility", {
                        proteinName: protein.name,
                        flexibility: bfactors.data
                    })
                }).then(() => context.getters.getApi.post(`/bfactors`, { // Loops
                        });
                        return residue_proimise.then(
                            (response) => wait_for_computation_async(context.getters.getApi, "flexibility", response.data.pid, 5000)
                        )
                    })(),
                    (() => {
                        let loops_promise = context.getters.getApi.post(`/flexibility/start_computation`, {
                            pdb: protein.name,
                            chain: protein.chain,
                            types: bfactors,
                            segmentation: protein.segmentation
                                .segments
                                .filter(segment => segment.type == SegmentationType.loop),
                    file: encodedFiles,
                            file: flexibility_files,
                            bfactor_aggregation_type: 'loop',
                            crosscorelation: true
                })).then(bfactors => {
                    for (let flex of bfactors.data.values) {
                        let flexibility = {}
                        for (let flextype of bfactors.data.types) {
                            flexibility[flextype] = roundToTwo(parseFloat(flex[flextype]))
                        });
                        return loops_promise.then(
                            (response) => wait_for_computation_async(context.getters.getApi, "flexibility", response.data.pid, 5000)
                        )
                    })(),
                    (() => {
                        let secs_promise = context.getters.getApi.post(`/flexibility/start_computation`, {
                            pdb: protein.name,
                            chain: protein.chain,
                            types: bfactors,
                            segmentation: protein.segmentation
                                .segments
                                .filter(segment => segment.type == SegmentationType.secondary_structure),
                            file: flexibility_files,
                            bfactor_aggregation_type: 'secs'

                        });
                        return secs_promise.then(
                            (response) => wait_for_computation_async(context.getters.getApi, "flexibility", response.data.pid, 5000)
                        )
                    })()
                ]
            ).then(([residue_response, loops_response, secs_response]) => {
                if (!residue_response.data.canBeRetrieved) {
                    throw new Error("Computation of flexibility per-residue has failed.")
                }
                if (!loops_response.data.canBeRetrieved) {
                    throw new Error("Computation of flexibility per-loop has failed.")
                }
                if (!secs_response.data.canBeRetrieved) {
                    throw new Error("Computation of flexibility per-secs has failed.")
                }

                        let segment = bfactors.data.segmentation.find(s => s.name == flex.segment);
                return Promise.all([
                    context.getters.getApi.get(`/flexibility/retrive/${residue_response.data.pid}`),
                    context.getters.getApi.get(`/flexibility/retrive/${loops_response.data.pid}`),
                    context.getters.getApi.get(`/flexibility/retrive/${secs_response.data.pid}`),
                ])

                        let crosscorelation_types = Object.keys(bfactors.data.cross_correlation);
            }).then((([residues, loops, secs]) => {
                //residues
                context.commit("addAcidsFlexibility", {
                    proteinName: protein.name,
                    flexibility: residues.data
                })
                //loops
                for (let flex of loops.data.values) {
                    let flexibility_dict = {}
                    for (let flextype of loops.data.types) {
                        flexibility_dict[flextype] = roundToTwo(parseFloat(flex[flextype]))
                    }

                    let segment = loops.data.segmentation.find(s => s.name == flex.segment);

                    let crosscorelation_types = Object.keys(loops.data.cross_correlation);
                    let ccors = {}
                    for (let type of crosscorelation_types) {
                        let ccors_dictionary = {};
                            let ccors_segments = bfactors.data.cross_correlation[type].segment_names;
                        let ccors_segments = loops.data.cross_correlation[type].segment_names;
                        ccors_dictionary = zipWith(
                                bfactors.data.cross_correlation[type].segment_dictionary[segment.name],
                            loops.data.cross_correlation[type].segment_dictionary[segment.name],
                            ccors_segments,
                            (value, loopId) => ({ loopId, value: roundToTwo(parseFloat(value)) })
                        )
@@ -589,7 +641,7 @@ export default {
                    context.commit("addLoopFlexibility", {
                        proteinName: protein.name,
                        loop_id: segment.name,
                            flexibility: flexibility,
                        flexibility: flexibility_dict,
                        crosscorelation: ccors
                    })
                    context.commit("addProteinCcorsTypes", {
@@ -600,38 +652,28 @@ export default {

                context.commit("addProteinFlexibilityTypes", {
                    proteinName: protein.name,
                        flexibility: bfactors.data
                    flexibility: loops.data
                })
                }).then(() => context.getters.getApi.post(`/bfactors`, { // Secondary Structures
                    pdb: protein.name,
                    chain: protein.chain,
                    types: bfactors,
                    segmentation: protein.segmentation
                        .segments
                        .filter(segment => segment.type == SegmentationType.secondary_structure),
                    file: encodedFiles,
                    bfactor_aggregation_type: 'secs'

                })).then((bfactors) => {
                //Secs
                context.commit("addProteinSecondaryStructureCrosscol", {
                    proteinName: protein.name,
                        crosscol: bfactors.data.cross_correlation
                    crosscol: secs.data.cross_correlation
                });
                context.commit("addProteinSecondaryStructureFlexibility", {
                    proteinName: protein.name,
                        flexibility: bfactors.data
                    flexibility: secs.data
                })
                }).catch(err => {
            })).catch(err => {
                context.dispatch("setErrorMessage", { error: err });
                throw err;
            });

            context.dispatch("addAwaitable", {
                id: _.uniqueId("awaiting"),
                promise: flexibility,
                promise: flexibility_computation,
                description: `Computing flexibility for ${protein.displayName}`
            });
            return flexibility;
            return flexibility_computation;
        },

        computeSuperloops(context, protein) {
@@ -712,16 +754,28 @@ export default {
        },

        computeLoops(context, proteinName) {
            console.log("starting loop comp...")
            let protein = context.getters.getProtein(proteinName);
            let request = context.getters.getApi.post(`/loops/compute`, {
            let request = context.getters.getApi.post(`/loops/start_computation`, {
                pdb: proteinName,
                chain: protein.chain,
                segmentation: new Segmentation(protein)
                    .segments
                    .filter(segment => segment.type == SegmentationType.secondary_structure)
            }).then((response) => {
            }).then((response) => {   //check until finished
                return Promise.all([wait_for_computation_async(context.getters.getApi, "loops", response.data.pid, 5000), response.data.pid])
            }).then(([response, pid]) => {
                console.log(response)
                if (!response.data.canBeRetrieved) {
                    throw new Error("Loops computation failed with unknown error.");
                }
                return context.getters.getApi.get(`/loops/retrive/${pid}`)
            }).then((response) => { //set
                context.dispatch("purgeNoncustomLoops", { proteinName: protein.name });
                context.dispatch("addLoops", { proteinName, geometries: response.data, source: "Computed" })
            }).catch(err => {
                context.dispatch("setErrorMessage", { error: err });
                throw err;
            });
            context.dispatch("addAwaitable", {
                id: _.uniqueId("awaiting"),
@@ -731,22 +785,6 @@ export default {

        },

        lookupArchDBLoops(context, proteinName) {
            let protein = context.getters.getProtein(proteinName);
            context.dispatch("purgeNoncustomLoops", { proteinName: protein.name });

            let request = context.getters.getApi.get(`/loops/lookup/${proteinName}/${protein.chain}`, {
                pdb: proteinName,
                chain: protein.chain
            }).then((response) => context.dispatch("addLoops", { proteinName, geometries: response.data, source: "ArchDB" }));
            context.dispatch("addAwaitable", {
                id: _.uniqueId("awaiting"),
                promise: request,
                description: `Downloading ArchDB loops for ${proteinName}`
            });


        },
        zoomToLoop(context, { protein, loop }) {
            context.commit("setThreeDProtein", { protein: protein, flexibility: null });
            context.commit("zoomToLoop", loop);