Loading src/store/modules/proteins.js +143 −105 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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)) }) ) Loading @@ -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", { Loading @@ -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) { Loading Loading @@ -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"), Loading @@ -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); Loading Loading
src/store/modules/proteins.js +143 −105 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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)) }) ) Loading @@ -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", { Loading @@ -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) { Loading Loading @@ -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"), Loading @@ -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); Loading