Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mark/1488 customize histogram calculations #2141

Merged
merged 54 commits into from
May 2, 2023
Merged
Show file tree
Hide file tree
Changes from 52 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
6d7b0a4
Add more variables in the SetHistogramRequirements message
markccchiang Feb 8, 2023
4bc624b
Add default pixel bounds in the histogram request message
markccchiang Feb 9, 2023
a6db935
Merge branch 'dev' of https://github.com/CARTAvis/carta-frontend into…
markccchiang Mar 13, 2023
cbe0c5b
Merge branch 'dev' of https://github.com/CARTAvis/carta-frontend into…
markccchiang Mar 17, 2023
ce3f174
Add a histogram config setting panel
markccchiang Mar 21, 2023
714a153
Add a handler for histogram generation with new config settings
markccchiang Mar 21, 2023
317a7f4
Update the protobuf with the new dev branch
markccchiang Mar 27, 2023
81fc407
Merge branch 'dev' of https://github.com/CARTAvis/carta-frontend into…
markccchiang Mar 27, 2023
25b9fe1
Modify the HistogramConfig message and add it to the RegionHistogramData
markccchiang Mar 27, 2023
c2453c0
Add histogram config setting to the protobuf message SetHistogramRequ…
markccchiang Mar 27, 2023
9f5c11e
Only update the channel histogram data if its configs for number of b…
markccchiang Mar 28, 2023
f2d896e
Render the correct histogram plot with respect to its configurations …
markccchiang Mar 28, 2023
bad55d3
Add a reset button to reset histogram configurations
markccchiang Mar 29, 2023
e32f1b0
Automatically generate a new histogram when new configurations are set
markccchiang Mar 29, 2023
1831eec
Refactor the HistogramConfigPanelComponent
markccchiang Mar 30, 2023
663b106
Change the format of histogram config panel
markccchiang Mar 31, 2023
5244992
Cache histogram config settings from automatically generated values
markccchiang Apr 11, 2023
4532dd8
Change the format of setting histogram number of bins panel
markccchiang Apr 11, 2023
74ca4d1
Fix the code style
markccchiang Apr 11, 2023
39f779d
Merge branch 'dev' of https://github.com/CARTAvis/carta-frontend into…
markccchiang Apr 12, 2023
215116f
Modify the tool tip text for the setting of maximum slider value
markccchiang Apr 12, 2023
d5bf354
Change the name of title for histogram configuration panel
markccchiang Apr 13, 2023
54f0be1
Set the lower bound of number of bins as 2
markccchiang Apr 13, 2023
a14e621
Redefine the equality of two numbers
markccchiang Apr 13, 2023
81971ea
Remove the bin width variable from histogram configuration message
markccchiang Apr 14, 2023
139edab
Change the order of histogram setting panels
markccchiang Apr 18, 2023
6345978
Reset the max number of bins when resetting the config
markccchiang Apr 18, 2023
d5b435d
Set the intent prop for pixel range fillers, and change the tooltips …
markccchiang Apr 18, 2023
26a0148
Move the warning message to tooltip and change the format of filler f…
markccchiang Apr 19, 2023
04be131
Remove an unused scss file
markccchiang Apr 19, 2023
3364aa6
Move the file HistogramConfigPanelComponent.tsx to folder HistogramSe…
markccchiang Apr 19, 2023
49390a2
Merge branch 'dev' of https://github.com/CARTAvis/carta-frontend into…
markccchiang Apr 20, 2023
d721313
Update the protobuf version in the index
markccchiang Apr 24, 2023
6a578aa
Replace the function of two numbers comparison with an existing one
markccchiang Apr 25, 2023
d874825
Remove the onKeyDown function from the max bin numbers filler
markccchiang Apr 25, 2023
8e514db
Set the constant parameter of min bin number as a private static read…
markccchiang Apr 25, 2023
db2d4f4
Call the function of updating config variables under the HistogramWid…
markccchiang Apr 25, 2023
dafa05f
Rename the config variables
markccchiang Apr 25, 2023
42c3a3e
Change the property and format of a reset config button
markccchiang Apr 25, 2023
a15e62a
Remove redundant functions from the HistogramWidgetStore
markccchiang Apr 25, 2023
15573e7
Remove the tooltip from a reset config button
markccchiang Apr 25, 2023
0e46dad
Refactor the codes for getting region histogram data
markccchiang Apr 26, 2023
db9fadb
Update the protobuf and change the type of histogram bounds to double
markccchiang Apr 26, 2023
8026fc8
Apply an autorun function in the HistogramWidgetStore
markccchiang Apr 26, 2023
2860e70
Minor code changes
markccchiang Apr 27, 2023
a0e2d84
Merge branch 'dev' of https://github.com/CARTAvis/carta-frontend into…
markccchiang Apr 27, 2023
5a64d20
Rename a variable and fix a typo
markccchiang Apr 27, 2023
d983aac
Remove a variable and simplify the code
markccchiang Apr 27, 2023
5da48f2
Add a check when setting the max number of bins for a slider
markccchiang Apr 27, 2023
cc667c2
Reset the max number of bins when configs are reset or auto bins is on
markccchiang Apr 27, 2023
ffe6813
Fix typos
markccchiang Apr 28, 2023
eeef886
Merge branch 'dev' of https://github.com/CARTAvis/carta-frontend into…
markccchiang May 2, 2023
cdcf1ff
fix crash issue 2150
YuHsuan-Hwang May 2, 2023
1eb70b1
update protobuf
YuHsuan-Hwang May 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Added supports for swapped-axes image cubes ([#1953](https://github.com/CARTAvis/carta-frontend/issues/1953)).
* Added supports for image annotations ([#267](https://github.com/CARTAvis/carta-frontend/issues/267)).
* Added the ability of changing to a new directory by entering a path ([#609](https://github.com/CARTAvis/carta-frontend/issues/609)).
* Added supports for customizing histogram calculations ([#1488](https://github.com/CARTAvis/carta-frontend/issues/1488)).
### Fixed
* Fixed the issue of annoying text input fields ([#1906](https://github.com/CARTAvis/carta-frontend/issues/1906)).
* Fixed the issues of copying the Session URL in the macOS Electron and Linux AppImage versions ([#2102](https://github.com/CARTAvis/carta-frontend/issues/2102), [#2108](https://github.com/CARTAvis/carta-frontend/issues/2108)).
Expand Down
184 changes: 111 additions & 73 deletions src/components/Histogram/HistogramComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {Point2D, POLARIZATIONS} from "models";
import {AppStore, DefaultWidgetConfig, HelpType, WidgetProps, WidgetsStore} from "stores";
import {FrameStore} from "stores/Frame";
import {HistogramWidgetStore} from "stores/Widgets";
import {binarySearchByX, clamp, getColorForTheme, toExponential, toFixed} from "utilities";
import {binarySearchByX, clamp, closeTo, getColorForTheme, toExponential, toFixed} from "utilities";

import {TickType} from "../Shared/LinePlot/PlotContainer/PlotContainerComponent";

Expand All @@ -37,6 +37,7 @@ export class HistogramComponent extends React.Component<WidgetProps> {
}

private cachedFrame: FrameStore;
private currentLinePlotProps: LinePlotComponentProps;

@observable width: number;
@observable height: number;
Expand All @@ -53,31 +54,25 @@ export class HistogramComponent extends React.Component<WidgetProps> {
return new HistogramWidgetStore();
}

@computed get histogramData(): CARTA.IHistogram {
const appStore = AppStore.Instance;

if (this.widgetStore.effectiveFrame) {
let fileId = this.widgetStore.effectiveFrame.frameInfo.fileId;
let regionId = this.widgetStore.effectiveRegionId;
let coordinate = this.widgetStore.coordinate;
@computed get isTargetData(): boolean {
const regionHistogramData = this.getRegionHistogramData();
if (!regionHistogramData) {
return false;
}

const frameMap = appStore.regionHistograms.get(fileId);
if (!frameMap) {
return null;
}
const regionMap = frameMap.get(regionId);
if (!regionMap) {
return null;
}
const stokesIndex = this.widgetStore.effectiveFrame.polarizationInfo.findIndex(polarization => polarization.replace("Stokes ", "") === coordinate.slice(0, coordinate.length - 1));
const stokes = stokesIndex >= this.widgetStore.effectiveFrame.frameInfo.fileInfoExtended.stokes ? this.widgetStore.effectiveFrame.polarizations[stokesIndex] : stokesIndex;
const regionHistogramData = regionMap.get(stokes === -1 ? this.widgetStore.effectiveFrame.requiredStokes : stokes);
if (!regionHistogramData) {
return null;
}
return regionHistogramData.histograms;
// Check whether the histogram data matches the widget's configuration
if (regionHistogramData.config.fixedNumBins !== this.widgetStore.fixedNumBins || regionHistogramData.config.fixedBounds !== this.widgetStore.fixedBounds) {
return false;
}
return null;
if (regionHistogramData.config.fixedNumBins && regionHistogramData.config.numBins !== this.widgetStore.numBins) {
return false;
}
return !regionHistogramData.config.fixedBounds || (closeTo(regionHistogramData.config.bounds.min, this.widgetStore.minPix) && closeTo(regionHistogramData.config.bounds.max, this.widgetStore.maxPix));
}

@computed get histogramData(): CARTA.IHistogram {
const regionHistogramData = this.getRegionHistogramData();
return regionHistogramData ? regionHistogramData.histograms : null;
}

@computed get plotData(): {values: Array<Point2D>; xMin: number; xMax: number; yMin: number; yMax: number} {
Expand All @@ -99,6 +94,18 @@ export class HistogramComponent extends React.Component<WidgetProps> {
let yMin = histogram.bins[minIndex];
let yMax = yMin;

// Cache automatic settings for histogram min and max values
if (this.widgetStore.currentAutoBounds) {
this.widgetStore.cacheBounds(xMin, xMax);
this.widgetStore.resetBounds();
}

// Cache automatic setting for the number of histogram bins
if (this.widgetStore.currentAutoBins) {
this.widgetStore.cacheNumBins(histogram.bins.length);
this.widgetStore.resetNumBins();
}

let values: Array<{x: number; y: number}>;
const N = maxIndex - minIndex;
if (N > 0 && !isNaN(N)) {
Expand Down Expand Up @@ -221,6 +228,33 @@ export class HistogramComponent extends React.Component<WidgetProps> {
return profilerInfo;
};

private getRegionHistogramData = (): CARTA.IRegionHistogramData => {
if (!this.widgetStore.effectiveFrame) {
return null;
}

const fileId = this.widgetStore.effectiveFrame.frameInfo.fileId;
const regionId = this.widgetStore.effectiveRegionId;
const coordinate = this.widgetStore.coordinate;
const appStore = AppStore.Instance;

const frameMap = appStore.regionHistograms.get(fileId);
if (!frameMap) {
return null;
}

const regionMap = frameMap.get(regionId);
if (!regionMap) {
return null;
}

const stokesIndex = this.widgetStore.effectiveFrame.polarizationInfo.findIndex(polarization => polarization.replace("Stokes ", "") === coordinate.slice(0, coordinate.length - 1));
const stokes = stokesIndex >= this.widgetStore.effectiveFrame.frameInfo.fileInfoExtended.stokes ? this.widgetStore.effectiveFrame.polarizations[stokesIndex] : stokesIndex;
const regionHistogramData = regionMap.get(stokes === -1 ? this.widgetStore.effectiveFrame.requiredStokes : stokes);

return regionHistogramData ? regionHistogramData : null;
};

render() {
const appStore = AppStore.Instance;
const frame = this.widgetStore.effectiveFrame;
Expand All @@ -246,59 +280,63 @@ export class HistogramComponent extends React.Component<WidgetProps> {

const imageName = frame.filename;
const plotName = `channel ${frame.channel} histogram`;
let linePlotProps: LinePlotComponentProps = {
xLabel: unit ? `Value (${unit})` : "Value",
yLabel: "Count",
darkMode: appStore.darkTheme,
imageName: imageName,
plotName: plotName,
logY: this.widgetStore.logScaleY,
plotType: this.widgetStore.plotType,
tickTypeY: TickType.Scientific,
graphZoomedX: this.widgetStore.setXBounds,
graphZoomedY: this.widgetStore.setYBounds,
graphZoomedXY: this.widgetStore.setXYBounds,
graphZoomReset: this.widgetStore.clearXYBounds,
graphCursorMoved: this.onGraphCursorMoved,
scrollZoom: true,
mouseEntered: this.widgetStore.setMouseMoveIntoLinePlots,
borderWidth: this.widgetStore.lineWidth,
pointRadius: this.widgetStore.linePlotPointSize,
zeroLineWidth: 2
};

if (frame.renderConfig.histogram && frame.renderConfig.histogram.bins && frame.renderConfig.histogram.bins.length) {
const currentPlotData = this.plotData;
if (currentPlotData) {
linePlotProps.data = currentPlotData.values;

// set line color
let primaryLineColor = getColorForTheme(this.widgetStore.primaryLineColor);
linePlotProps.lineColor = primaryLineColor;

// Determine scale in X and Y directions. If auto-scaling, use the bounds of the current data
if (this.widgetStore.isAutoScaledX) {
linePlotProps.xMin = currentPlotData.xMin;
linePlotProps.xMax = currentPlotData.xMax;
} else {
linePlotProps.xMin = this.widgetStore.minX;
linePlotProps.xMax = this.widgetStore.maxX;
}
if (this.isTargetData || !this.currentLinePlotProps) {
let linePlotProps: LinePlotComponentProps = {
xLabel: unit ? `Value (${unit})` : "Value",
yLabel: "Count",
darkMode: appStore.darkTheme,
imageName: imageName,
plotName: plotName,
logY: this.widgetStore.logScaleY,
plotType: this.widgetStore.plotType,
tickTypeY: TickType.Scientific,
graphZoomedX: this.widgetStore.setXBounds,
graphZoomedY: this.widgetStore.setYBounds,
graphZoomedXY: this.widgetStore.setXYBounds,
graphZoomReset: this.widgetStore.clearXYBounds,
graphCursorMoved: this.onGraphCursorMoved,
scrollZoom: true,
mouseEntered: this.widgetStore.setMouseMoveIntoLinePlots,
borderWidth: this.widgetStore.lineWidth,
pointRadius: this.widgetStore.linePlotPointSize,
zeroLineWidth: 2
};

if (frame.renderConfig.histogram && frame.renderConfig.histogram.bins && frame.renderConfig.histogram.bins.length) {
const currentPlotData = this.plotData;
if (currentPlotData) {
linePlotProps.data = currentPlotData.values;

// set line color
linePlotProps.lineColor = getColorForTheme(this.widgetStore.primaryLineColor);

// Determine scale in X and Y directions. If auto-scaling, use the bounds of the current data
if (this.widgetStore.isAutoScaledX) {
linePlotProps.xMin = currentPlotData.xMin;
linePlotProps.xMax = currentPlotData.xMax;
} else {
linePlotProps.xMin = this.widgetStore.minX;
linePlotProps.xMax = this.widgetStore.maxX;
}

if (this.widgetStore.isAutoScaledY) {
linePlotProps.yMin = currentPlotData.yMin;
linePlotProps.yMax = currentPlotData.yMax;
} else {
linePlotProps.yMin = this.widgetStore.minY;
linePlotProps.yMax = this.widgetStore.maxY;
}
// Fix log plot min bounds for entries with zeros in them
if (this.widgetStore.logScaleY && linePlotProps.yMin <= 0) {
linePlotProps.yMin = 0.5;
if (this.widgetStore.isAutoScaledY) {
linePlotProps.yMin = currentPlotData.yMin;
linePlotProps.yMax = currentPlotData.yMax;
} else {
linePlotProps.yMin = this.widgetStore.minY;
linePlotProps.yMax = this.widgetStore.maxY;
}
// Fix log plot min bounds for entries with zeros in them
if (this.widgetStore.logScaleY && linePlotProps.yMin <= 0) {
linePlotProps.yMin = 0.5;
}
}

linePlotProps.comments = this.exportHeaders;
}

linePlotProps.comments = this.exportHeaders;
this.currentLinePlotProps = linePlotProps;
}

const className = classNames("histogram-widget", {"bp3-dark": appStore.darkTheme});
Expand All @@ -308,7 +346,7 @@ export class HistogramComponent extends React.Component<WidgetProps> {
<div className="histogram-container">
<HistogramToolbarComponent widgetStore={this.widgetStore} />
<div className="histogram-plot">
<LinePlotComponent {...linePlotProps} />
<LinePlotComponent {...this.currentLinePlotProps} />
</div>
<div>
<ProfilerInfoComponent info={this.genProfilerInfo(unit)} />
Expand Down
Loading