Skip to content

Commit

Permalink
Merge pull request #331 from Kitware/feat/tile-compositing/244
Browse files Browse the repository at this point in the history
Add compositing
  • Loading branch information
luciemac authored Feb 7, 2023
2 parents 6bb3761 + 660338d commit c223062
Show file tree
Hide file tree
Showing 3 changed files with 530 additions and 321 deletions.
35 changes: 21 additions & 14 deletions src/store/GirderAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,12 @@ export default class GirderAPI {
return this.client.get(`item/${toId(item)}/tiles`).then(r => r.data);
}

getTilesInternalMetadata(item: string | IGirderItem): Promise<any> {
return this.client
.get(`item/${toId(item)}/tiles/internal_metadata`)
.then(r => r.data);
}

private getHistogram(
item: string | IGirderItem,
options: Partial<IHistogramOptions> = {}
Expand Down Expand Up @@ -298,20 +304,21 @@ export default class GirderAPI {
): Promise<IDataset> {
return Promise.all([this.getFolder(id), this.getItems(id)]).then(
([folder, items]) => {
// just use the first image
const images = items.filter(d => (d as any).largeImage).slice(0, 1);
return Promise.all(images.map(item => this.getTiles(item))).then(
tiles => {
const configurations = items
.filter(isConfigurationItem)
.map(asConfigurationItem);
return {
...asDataset(folder),
configurations,
...parseTiles(images[0], tiles[0], unrollXY, unrollZ, unrollT)
};
}
);
// just use the first image if it exists
const folderDataset = asDataset(folder);
const imageItem = items.find(d => (d as any).largeImage);
const configurations = items
.filter(isConfigurationItem)
.map(asConfigurationItem);
const baseDataset = { ...folderDataset, configurations };
if (imageItem === undefined) {
return baseDataset;
} else {
return this.getTiles(imageItem).then(tiles => ({
...baseDataset,
...parseTiles(imageItem, tiles, unrollXY, unrollZ, unrollT)
}));
}
}
);
}
Expand Down
145 changes: 65 additions & 80 deletions src/utils/parsing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,23 +134,23 @@ export function splitFilenames(filenames: string[]): string[][] {
});
}

const enumType: { [index: string]: string } = {
t: "t",
time: "t",
timepoint: "t",
s: "xy",
stage: "xy",
position: "xy",
xy: "xy",
XY: "xy",
z: "z",
Z: "z",
slice: "z",
chann: "chan",
channel: "chan"
const enumType: { [index: string]: TDimensions } = {
t: "T",
time: "T",
timepoint: "T",
s: "XY",
stage: "XY",
position: "XY",
xy: "XY",
XY: "XY",
z: "Z",
Z: "Z",
slice: "Z",
chann: "C",
channel: "C"
};

export function getStringType(inputString: string): string | undefined {
export function getStringType(inputString: string): TDimensions | undefined {
return enumType[inputString];
}

Expand All @@ -173,85 +173,70 @@ export function getFields(filenames: string[][]) {
});
}

export type TDimensions = "XY" | "Z" | "T" | "C";

export interface IVariableGuess {
guess: TDimensions; // Guessed dimension
values: string[]; // All the values for this dimension (a list of unique strings)
valueIdxPerFilename: {
[key: string]: number; // Index of the value for each filename
};
}

export function collectFilenameMetadata2(
filenames: string[]
): {
metadata: {
[key: string]: string[];
t: string[];
xy: string[];
z: string[];
chan: string[];
};
filesInfo: {
[key: string]: { [key: string]: number[] };
};
} {
): IVariableGuess[] {
// Convert annoying date format to time
const convertedFilenames = filenames.map(filename =>
convertDateToTime(filename)
);

// Split up the filenames with delimiters
// Get a matrix of values: filenamesSplit[fileIdx][variableIdx]
const filenamesSplit: string[][] = splitFilenames(convertedFilenames);

const output: {
[key: string]: string[];
t: string[];
xy: string[];
z: string[];
chan: string[];
} = {
t: [],
xy: [],
z: [],
chan: []
};
const filesInfo: {
[key: string]: { [key: string]: number[] };
} = {};
const guesses: IVariableGuess[] = [];

// A list of variables
const fieldsElements = getFields(filenamesSplit);
fieldsElements.forEach((fieldElement, index) => {

fieldsElements.forEach((fieldElement, variableIdx) => {
const { values, numberOfElement, isNumeric } = fieldElement;
let typename: string | undefined = undefined;
if (numberOfElement > 1) {
if (isNumeric) {
typename =
index > 0 && fieldsElements[index - 1].numberOfElement === 1
? getStringType(fieldsElements[index - 1].values[0])
: "xy";
} else {
// If we just have a bunch of names, then assume it's a channel
typename = "chan";
}
if (typename) {
output[typename].push(...values);

filenamesSplit.forEach((split, j) => {
const filename = filenames[j];
if (!filesInfo[filename]) {
filesInfo[filename] = {
t: [],
xy: [],
z: [],
chan: []
};
}
if (typename) {
const val: string = split[index];
const foundIndex = output[typename].indexOf(val);
if (foundIndex > -1) {
filesInfo[filename][typename].push(foundIndex);
}
}
});
}
values.sort((a, b) => a.localeCompare(b));

// Guess an ID (XY, Z, T, C) for this variable
let typename: TDimensions | undefined = undefined;
if (numberOfElement <= 1) {
return;
}
if (isNumeric) {
typename =
variableIdx > 0 && fieldsElements[variableIdx - 1].numberOfElement === 1
? getStringType(fieldsElements[variableIdx - 1].values[0])
: "XY";
} else {
// If we just have a bunch of names, then assume it's a channel
typename = "C";
}

// If an ID was guessed, add the guess to the list
if (typename) {
const valueIdxPerFilename: { [key: string]: number } = {};
filenames.forEach((filename, filenameIdx) => {
const filenameValue = filenamesSplit[filenameIdx][variableIdx];
// We know that filenameValue is in values thanks to the implementation of getFields
valueIdxPerFilename[filename] = values.findIndex(
value => value === filenameValue
);
});
const guess: IVariableGuess = {
guess: typename,
values: [...values],
valueIdxPerFilename
};
guesses.push(guess);
}
});

return {
metadata: output,
filesInfo
};
return guesses;
}
Loading

0 comments on commit c223062

Please sign in to comment.