Skip to content

Commit

Permalink
Preview for the HCS images (#2489) - Flip wells map vertically; fetch…
Browse files Browse the repository at this point in the history
… wells_map.json using signed urls
  • Loading branch information
rodichenko committed Feb 9, 2022
1 parent 1da1dc0 commit 47d2163
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,19 @@
width: 100%;
}

.rows.flip .legend {
flex-direction: column-reverse;
}

.columns .legend {
flex-direction: row;
height: 100%;
}

.columns.flip .legend {
flex-direction: row-reverse;
}

.legend .legend-item {
display: flex;
align-items: center;
Expand Down
66 changes: 44 additions & 22 deletions client/src/components/special/hcs-image/hcs-control-grid/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -269,11 +269,21 @@ class HcsControlGrid extends React.Component {
} = event.nativeEvent || {};
let cell;
if (offsetX !== undefined && offsetY !== undefined) {
const column = Math.floor(offsetX / cellSize);
const row = Math.floor(offsetY / cellSize);
let column = Math.floor(offsetX / cellSize);
let row = Math.floor(offsetY / cellSize);
const {
dataCells = []
dataCells = [],
flipVertical,
flipHorizontal,
columns,
rows
} = this.props;
if (flipHorizontal) {
column = columns - column;
}
if (flipVertical) {
row = rows - row;
}
cell = (dataCells.find(o => o.row === row && o.column === column));
}
return cell;
Expand Down Expand Up @@ -323,7 +333,9 @@ class HcsControlGrid extends React.Component {
dataCells = [],
selectedCell,
gridShape = Shapes.rect,
gridRadius = 0
gridRadius = 0,
flipVertical,
flipHorizontal
} = this.props;
let {
cellShape = Shapes.circle
Expand All @@ -336,6 +348,10 @@ class HcsControlGrid extends React.Component {
cancelAnimationFrame(this.drawHandle);
}
const correctPixels = o => o * window.devicePixelRatio;
const getX = column =>
correctPixels((flipHorizontal ? (columns - column) : column) * cellSize);
const getY = row =>
correctPixels((flipVertical ? (rows - row) : row) * cellSize);
this.drawHandle = requestAnimationFrame(() => {
let color = 'rgba(0, 0, 0, 0.65)';
let dataColor = '#108ee9';
Expand All @@ -353,17 +369,17 @@ class HcsControlGrid extends React.Component {
const renderCell = (column, row) => {
if (cellShape === Shapes.circle) {
context.arc(
Math.round(correctPixels((column + 0.5) * cellSize)),
Math.round(correctPixels((row + 0.5) * cellSize)),
Math.round(getX(column + 0.5)),
Math.round(getY(row + 0.5)),
correctPixels(radius),
0,
Math.PI * 2
);
}
if (cellShape === Shapes.rect) {
context.rect(
Math.round(correctPixels(column * cellSize)),
Math.round(correctPixels(row * cellSize)),
Math.round(getX(column)),
Math.round(getY(row)),
Math.round(correctPixels(cellSize)),
Math.round(correctPixels(cellSize))
);
Expand Down Expand Up @@ -412,22 +428,22 @@ class HcsControlGrid extends React.Component {
context.beginPath();
for (let c = 1; c <= columns; c += 1) {
context.moveTo(
correctPixels(c * cellSize),
getX(c),
0
);
context.lineTo(
correctPixels(c * cellSize),
getX(c),
this.canvas.height
);
}
for (let r = 1; r <= rows; r += 1) {
context.moveTo(
0,
correctPixels(r * cellSize)
getY(r)
);
context.lineTo(
this.canvas.width,
correctPixels(r * cellSize)
getY(r)
);
}
context.stroke();
Expand All @@ -439,17 +455,17 @@ class HcsControlGrid extends React.Component {
context.strokeStyle = color;
context.lineWidth = 2;
context.arc(
Math.round(correctPixels(columns / 2.0 * cellSize)),
Math.round(correctPixels(rows / 2.0 * cellSize)),
Math.round(getX(columns / 2.0)),
Math.round(getY(rows / 2.0)),
Math.round(correctPixels(cellSize * gridRadius)),
0,
Math.PI * 2
);
context.stroke();
context.beginPath();
context.arc(
correctPixels(columns / 2.0 * cellSize),
correctPixels(rows / 2.0 * cellSize),
getX(columns / 2.0),
getY(rows / 2.0),
correctPixels(3),
0,
Math.PI * 2
Expand All @@ -469,7 +485,9 @@ class HcsControlGrid extends React.Component {
style,
rows,
columns,
controlledHeight
controlledHeight,
flipHorizontal,
flipVertical
} = this.props;
const {
cellSize,
Expand All @@ -491,8 +509,9 @@ class HcsControlGrid extends React.Component {
className={
classNames(
styles.rows,
'cp-divider',
'right'
{
[styles.flip]: flipVertical
}
)
}
>
Expand All @@ -506,8 +525,9 @@ class HcsControlGrid extends React.Component {
className={
classNames(
styles.columns,
'cp-divider',
'bottom'
{
[styles.flip]: flipHorizontal
}
)
}
>
Expand Down Expand Up @@ -583,7 +603,9 @@ HcsControlGrid.propTypes = {
]),
gridRadius: PropTypes.number,
controlledHeight: PropTypes.bool,
allowEmptySpaces: PropTypes.bool
allowEmptySpaces: PropTypes.bool,
flipVertical: PropTypes.bool,
flipHorizontal: PropTypes.bool
};

HcsControlGrid.defaultProps = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class HcsImageFieldSelector extends React.Component {
cellShape={HcsControlGrid.Shapes.rect}
gridShape={HcsControlGrid.Shapes.circle}
gridRadius={wellRadius}
flipVertical
/>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,37 @@ function parseCoordinates (key) {
/**
* @typedef {Object} HCSSequenceInfo
* @property {string|number} storageId
* @property {string} omeTiffFileName
* @property {string} offsetsJsonFileName
* @property {string} wellsMap
* @property {string} wellsMapFileName
*/

/**
*
* @param {HCSSequenceInfo} sequence
* @returns {Promise<unknown>}
* Fetches wells_map.json content as JSON object
* @param {HCSSequenceInfo} options
* @return {Promise<Object>}
*/
export default function fetchSequenceWellsInfo (sequence) {
function fetchWellsMapJSON (options = {}) {
const {
storageId,
wellsMap,
wellsMapFileName
} = sequence;
if (!storageId || !wellsMapFileName) {
// eslint-disable-next-line
return Promise.reject(new Error('`storageId` and `wellsMapFileName` must be specified for HCS sequence'));
} = options;
if (wellsMap) {
return new Promise(async (resolve, reject) => {
try {
const response = await fetch(wellsMap);
if (!response.ok) {
throw new Error(
response.statusText ||
`Error fetching wells map content for url "${wellsMap}"`
);
}
const json = await response.json();
resolve(json);
} catch (e) {
reject(e);
}
});
}
return new Promise(async (resolve, reject) => {
const request = new DataStorageItemContent(storageId, wellsMapFileName);
Expand All @@ -59,6 +72,31 @@ export default function fetchSequenceWellsInfo (sequence) {
}
const text = atob(request.value.content);
const json = JSON.parse(text);
resolve(json);
} catch (e) {
reject(e);
}
});
}

/**
*
* @param {HCSSequenceInfo} sequence
* @returns {Promise<unknown>}
*/
export default function fetchSequenceWellsInfo (sequence) {
const {
storageId,
wellsMap,
wellsMapFileName
} = sequence;
if (!storageId || (!wellsMapFileName && !wellsMap)) {
// eslint-disable-next-line
return Promise.reject(new Error('`storageId` and `wellsMapFileName` must be specified for HCS sequence'));
}
return new Promise(async (resolve, reject) => {
try {
const json = await fetchWellsMapJSON(sequence);
resolve(
Object.keys(json || {})
.map(key => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ class HCSImageSequence {

fetch () {
if (!this._fetch) {
this._fetch = fetchSequenceWellsInfo(this);
this._fetch = new Promise((resolve, reject) => {
this.generateWellsMapURL()
.then(() => fetchSequenceWellsInfo(this))
.then(resolve)
.catch(reject);
});
this._fetch
.then((wells = []) => {
this.wells = wells.slice();
Expand All @@ -76,6 +81,22 @@ class HCSImageSequence {
return this._fetch;
}

generateWellsMapURL () {
const promise = generateHCSFileURLs({
s3Storage: this.s3Storage,
storageId: this.storageId,
path: this.wellsMapFileName
});
promise
.then((url) => {
this.wellsMap = url;
})
.catch((e) => {
this.error = e.message;
});
return promise;
}

generateOMETiffURL () {
const promise = generateHCSFileURLs({
s3Storage: this.s3Storage,
Expand Down

0 comments on commit 47d2163

Please sign in to comment.