mirror of
https://gitlab.com/wgp/dougal/software.git
synced 2025-12-06 10:17:07 +00:00
Refactor sequenceBinaryData.
It is no longer a computed property but actual data. It gets recalculated on demand via getSequenceBinaryData().
This commit is contained in:
@@ -578,6 +578,7 @@ export default {
|
|||||||
layerSelection: [],
|
layerSelection: [],
|
||||||
layersAvailable: {},
|
layersAvailable: {},
|
||||||
sequenceDataElements: [],
|
sequenceDataElements: [],
|
||||||
|
sequenceBinaryData: { positions: new Float32Array(0), values: [], udv: 2 },
|
||||||
sequenceDataTStamp: null,
|
sequenceDataTStamp: null,
|
||||||
loadingProgress: null,
|
loadingProgress: null,
|
||||||
viewState: {},
|
viewState: {},
|
||||||
@@ -613,99 +614,14 @@ export default {
|
|||||||
return this.sequenceDataElements?.map( el => el.data );
|
return this.sequenceDataElements?.map( el => el.data );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
sequenceBinaryData() {
|
sequenceBinaryData() {
|
||||||
const sequences = this.sequenceDataElements?.sort((a, b) => a.sequence - b.sequence) || [];
|
return this.getSequenceBinaryData(2); // Raw + gun data
|
||||||
if (!sequences.length) {
|
|
||||||
console.warn('No sequence data available');
|
|
||||||
return { positions: new Float32Array(0), values: [], udv: 2 };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate first sequence to get array sizes
|
|
||||||
let firstBundle;
|
|
||||||
try {
|
|
||||||
firstBundle = DougalBinaryBundle.clone(sequences[0].data);
|
|
||||||
if (!firstBundle.chunks || typeof firstBundle.chunks !== 'function') {
|
|
||||||
throw new Error('Invalid DougalBinaryBundle: chunks method missing');
|
|
||||||
}
|
|
||||||
if (!firstBundle.chunks().length) {
|
|
||||||
throw new Error('Invalid DougalBinaryBundle: bundle has no chunks');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to process first sequence:', e);
|
|
||||||
return { positions: new Float32Array(0), values: [], udv: 2 };
|
|
||||||
}
|
|
||||||
|
|
||||||
const totalCount = sequences.reduce((acc, { data }) => {
|
|
||||||
try {
|
|
||||||
const bundle = DougalBinaryBundle.clone(data);
|
|
||||||
return acc + bundle.chunks().reduce((sum, chunk) => sum + chunk.jCount, 0);
|
|
||||||
} catch (e) {
|
|
||||||
console.warn('Skipping invalid sequence data:', e);
|
|
||||||
return acc;
|
|
||||||
}
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
if (totalCount === 0) {
|
|
||||||
console.warn('No valid points found in sequences');
|
|
||||||
return { positions: new Float32Array(0), values: [], udv: 2 };
|
|
||||||
}
|
|
||||||
|
|
||||||
const ΔelemCount = firstBundle.chunks()[0].ΔelemCount;
|
|
||||||
const elemCount = firstBundle.chunks()[0].elemCount;
|
|
||||||
const positions = new Float32Array(totalCount * 2);
|
|
||||||
const values = new Array(ΔelemCount + elemCount + 2);
|
|
||||||
for (let k = 0; k < values.length; k++) {
|
|
||||||
values[k] = new (k === 0 ? Uint16Array : k === 1 ? Uint32Array : k === 2 ? BigUint64Array : Float32Array)(totalCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
let offset = 0;
|
|
||||||
let udv = 2;
|
|
||||||
sequences.forEach(({ data, sequence }) => {
|
|
||||||
try {
|
|
||||||
const bundle = DougalBinaryBundle.clone(data);
|
|
||||||
const chunks = bundle.chunks();
|
|
||||||
if (!chunks.length) {
|
|
||||||
console.warn(`No chunks in sequence ${sequence}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
udv = chunks[0].udv;
|
|
||||||
|
|
||||||
let chunkOffset = offset;
|
|
||||||
for (const chunk of chunks) {
|
|
||||||
const λarray = chunk.elem(0);
|
|
||||||
const φarray = chunk.elem(1);
|
|
||||||
for (let i = 0; i < λarray.length; i++) {
|
|
||||||
positions[chunkOffset * 2 + i * 2] = λarray[i];
|
|
||||||
positions[chunkOffset * 2 + i * 2 + 1] = φarray[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
values[0].set(new Uint16Array(chunk.jCount).fill(chunk.i), chunkOffset);
|
|
||||||
values[1].set(Uint32Array.from({ length: chunk.jCount }, (_, i) => chunk.j0 + i * chunk.Δj), chunkOffset);
|
|
||||||
|
|
||||||
for (let j = 0; j < chunk.ΔelemCount; j++) {
|
|
||||||
values[2 + j].set(chunk.Δelem(j), chunkOffset);
|
|
||||||
}
|
|
||||||
for (let j = 2; j < chunk.elemCount; j++) {
|
|
||||||
values[2 + chunk.ΔelemCount + j - 2].set(chunk.elem(j), chunkOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
chunkOffset += chunk.jCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += chunkOffset - offset;
|
|
||||||
} catch (e) {
|
|
||||||
console.warn(`Error processing sequence ${sequence}:`, e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (offset !== totalCount) {
|
|
||||||
console.warn(`Offset mismatch: ${offset} ≠ ${totalCount}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Concatenated ${totalCount} points, ${values.length} value arrays`);
|
|
||||||
return { positions, values, udv };
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
|
||||||
heatmapTitle () {
|
heatmapTitle () {
|
||||||
|
|
||||||
let title = this.heatmapValue;
|
let title = this.heatmapValue;
|
||||||
@@ -929,6 +845,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
await this.$root.sleep(300);
|
await this.$root.sleep(300);
|
||||||
|
this.sequenceDataElements = [];
|
||||||
this.getSequenceData();
|
this.getSequenceData();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1087,12 +1004,14 @@ export default {
|
|||||||
return [[λ0 - mλ, φ0 - mφ], [λ1 + mλ, φ1 + mφ]];
|
return [[λ0 - mλ, φ0 - mφ], [λ1 + mλ, φ1 + mφ]];
|
||||||
},
|
},
|
||||||
|
|
||||||
async getSequenceData () {
|
async getSequenceData (sequenceNumbers, types = [2, 3]) {
|
||||||
|
|
||||||
const types = ["p", "R", "F"];
|
//const types = [2, 3]; // Bundle types: 2 → raw/gun data; 3 ‒ final data. See bundles.js
|
||||||
const sequenceList = await this.api([`/project/${this.$route.params.project}/sequence`]);
|
|
||||||
// FIXME if sequenceList is undefined the API call failed. It should error and maybe retry
|
if (!sequenceNumbers) {
|
||||||
const sequenceNumbers = sequenceList.map(i => i.sequence);
|
const sequenceList = await this.api([`/project/${this.$route.params.project}/sequence`]);
|
||||||
|
sequenceNumbers = sequenceList?.map(i => i.sequence) ?? [];
|
||||||
|
}
|
||||||
const sequenceCount = sequenceNumbers.length * types.length;
|
const sequenceCount = sequenceNumbers.length * types.length;
|
||||||
let count = 0;
|
let count = 0;
|
||||||
|
|
||||||
@@ -1129,33 +1048,141 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const sequence of sequenceNumbers) {
|
for (const sequence of sequenceNumbers) {
|
||||||
try {
|
for (const type of types) {
|
||||||
const url = `/project/${self.$route.params.project}/sequence/${sequence}?type=2`;
|
try {
|
||||||
|
const url = `/project/${self.$route.params.project}/sequence/${sequence}?type=${type}`;
|
||||||
|
|
||||||
const sequenceData = await download(url);
|
const sequenceData = await download(url);
|
||||||
if (sequenceData) {
|
if (sequenceData) {
|
||||||
yield {
|
yield {
|
||||||
id: `seq-${sequence}`,
|
id: `seq-${sequence}-${type}`,
|
||||||
sequence: sequence,
|
sequence: sequence,
|
||||||
data: sequenceData.data
|
type: type,
|
||||||
};
|
data: sequenceData.data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Error downloading sequence ${sequence}`);
|
||||||
|
console.error(err);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
|
||||||
console.error(`Error downloading sequence ${sequence}`);
|
|
||||||
console.error(err);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const transferData = () => {
|
||||||
|
this.sequenceBinaryData = this.getSequenceBinaryData(2);
|
||||||
|
this.sequenceBinaryDataFinal = this.getSequenceBinaryData(3);
|
||||||
|
};
|
||||||
|
|
||||||
for await (const value of iterator()) {
|
for await (const value of iterator()) {
|
||||||
this.loadingProgress = ++count/sequenceCount*100;
|
this.loadingProgress = ++count/sequenceCount*100;
|
||||||
//console.log("PRG", count, sequenceCount, this.loadingProgress, );
|
//console.log("PRG", count, sequenceCount, this.loadingProgress, );
|
||||||
this.sequenceDataElements.push(Object.freeze(value));
|
this.sequenceDataElements.push(Object.freeze(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transferData();
|
||||||
|
|
||||||
this.loadingProgress = null;
|
this.loadingProgress = null;
|
||||||
console.log("passed for await", deck);
|
console.log("passed for await", deck);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getSequenceBinaryData (type) {
|
||||||
|
const sequences = this.sequenceDataElements?.filter( el => el.type == type)?.sort((a, b) => a.sequence - b.sequence) || [];
|
||||||
|
if (!sequences.length) {
|
||||||
|
console.warn('No sequence data available');
|
||||||
|
return { positions: new Float32Array(0), values: [], udv: type };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate first sequence to get array sizes
|
||||||
|
let firstBundle;
|
||||||
|
try {
|
||||||
|
firstBundle = DougalBinaryBundle.clone(sequences[0].data);
|
||||||
|
if (!firstBundle.chunks || typeof firstBundle.chunks !== 'function') {
|
||||||
|
throw new Error('Invalid DougalBinaryBundle: chunks method missing');
|
||||||
|
}
|
||||||
|
if (!firstBundle.chunks().length) {
|
||||||
|
throw new Error('Invalid DougalBinaryBundle: bundle has no chunks');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to process first sequence:', e);
|
||||||
|
return { positions: new Float32Array(0), values: [], udv: type };
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalCount = sequences.reduce((acc, { data }) => {
|
||||||
|
try {
|
||||||
|
const bundle = DougalBinaryBundle.clone(data);
|
||||||
|
return acc + bundle.chunks().reduce((sum, chunk) => sum + chunk.jCount, 0);
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Skipping invalid sequence data:', e);
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
if (totalCount === 0) {
|
||||||
|
console.warn('No valid points found in sequences');
|
||||||
|
return { positions: new Float32Array(0), values: [], udv: type };
|
||||||
|
}
|
||||||
|
|
||||||
|
const ΔelemCount = firstBundle.chunks()[0].ΔelemCount;
|
||||||
|
const elemCount = firstBundle.chunks()[0].elemCount;
|
||||||
|
const positions = new Float32Array(totalCount * 2);
|
||||||
|
const values = new Array(ΔelemCount + elemCount + 2);
|
||||||
|
for (let k = 0; k < values.length; k++) {
|
||||||
|
values[k] = new (k === 0 ? Uint16Array : k === 1 ? Uint32Array : k === 2 ? BigUint64Array : Float32Array)(totalCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
let offset = 0;
|
||||||
|
let udv = 2;
|
||||||
|
sequences.forEach(({ data, sequence }) => {
|
||||||
|
try {
|
||||||
|
const bundle = DougalBinaryBundle.clone(data);
|
||||||
|
const chunks = bundle.chunks();
|
||||||
|
if (!chunks.length) {
|
||||||
|
console.warn(`No chunks in sequence ${sequence}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
udv = chunks[0].udv;
|
||||||
|
|
||||||
|
if (udv != type) {
|
||||||
|
console.warn(`Found bundle with udv = ${udv} but I'm only expecting udv = ${type}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let chunkOffset = offset;
|
||||||
|
for (const chunk of chunks) {
|
||||||
|
const λarray = chunk.elem(0);
|
||||||
|
const φarray = chunk.elem(1);
|
||||||
|
for (let i = 0; i < λarray.length; i++) {
|
||||||
|
positions[chunkOffset * 2 + i * 2] = λarray[i];
|
||||||
|
positions[chunkOffset * 2 + i * 2 + 1] = φarray[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
values[0].set(new Uint16Array(chunk.jCount).fill(chunk.i), chunkOffset);
|
||||||
|
values[1].set(Uint32Array.from({ length: chunk.jCount }, (_, i) => chunk.j0 + i * chunk.Δj), chunkOffset);
|
||||||
|
|
||||||
|
for (let j = 0; j < chunk.ΔelemCount; j++) {
|
||||||
|
values[2 + j].set(chunk.Δelem(j), chunkOffset);
|
||||||
|
}
|
||||||
|
for (let j = 2; j < chunk.elemCount; j++) {
|
||||||
|
values[2 + chunk.ΔelemCount + j - 2].set(chunk.elem(j), chunkOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
chunkOffset += chunk.jCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += chunkOffset - offset;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(`Error processing sequence ${sequence}:`, e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (offset !== totalCount) {
|
||||||
|
console.warn(`Offset mismatch: ${offset} ≠ ${totalCount}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Concatenated ${totalCount} points, ${values.length} value arrays`);
|
||||||
|
return { positions, values, udv };
|
||||||
|
},
|
||||||
|
|
||||||
async initLayers (gl) {
|
async initLayers (gl) {
|
||||||
//console.log("SHOULD BE INITIALISING LAYERS HERE", gl);
|
//console.log("SHOULD BE INITIALISING LAYERS HERE", gl);
|
||||||
this.decodeURL();
|
this.decodeURL();
|
||||||
|
|||||||
Reference in New Issue
Block a user