feat: 完成Fitting功能

This commit is contained in:
Xu Zhimeng 2023-08-02 18:03:20 +08:00
parent 6456b949e7
commit 8f019687a4
2 changed files with 241 additions and 52 deletions

View File

@ -72,6 +72,7 @@
</a-form-model>
<a-button type="primary" @click="handleAddChannelAndEnergy">Add</a-button>
</div>
<!-- 表格开始 -->
<a-table
size="small"
:columns="columns"
@ -84,6 +85,7 @@
<a-icon type="delete" style="color: #f00;" @click="handleDel(index)"></a-icon>
</template>
</a-table>
<!-- 表格结束 -->
</div>
</div>
<div class="figure">
@ -120,14 +122,17 @@
<span>C to E : </span>
<span>
E =
<a-input type="number" size="small" v-model="newCalibrationFuncModel[0]" /> +
<a-input type="number" size="small" v-model="newCalibrationFuncModel[1]" /> *C +
<a-input type="number" size="small" v-model="newCalibrationFuncModel[2]" /> *C <sup>2</sup>
<a-input type="number" size="small" v-model="newCalibrationFuncModel.paramA" /> +
<a-input type="number" size="small" v-model="newCalibrationFuncModel.paramB" /> *C +
<a-input type="number" size="small" v-model="newCalibrationFuncModel.paramC" /> *C <sup>2</sup>
</span>
</p>
<div class="func">
<span>E to C : </span>
<span>C = 0 + 0 *E + 0 *E <sup>2</sup> </span>
<span
>C = {{ scientificNotationStr2Fixed(newE2C[0]) }} + {{ scientificNotationStr2Fixed(newE2C[0]) }} *E
+ {{ scientificNotationStr2Fixed(newE2C[0]) }} *E <sup>2</sup>
</span>
</div>
</title-over-border>
</div>
@ -333,6 +338,18 @@ const initialGammaGatedChartOption = {
itemStyle: {
color: '#04ADD9'
},
areaStyle: {
color: new graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: 'rgba(4, 173, 217, 0.87)'
},
{
offset: 1,
color: 'rgba(4, 173, 217, 0.05)'
}
])
},
symbol: 'none',
data: [],
markLine: {
@ -366,9 +383,18 @@ const initialFigureChartOption = {
}
},
formatter: params => {
const [channel, energy] = params[0].value
return `<div class="channel">Channel: ${channel}</div>
<div class="energy">Energy: ${energy.toFixed(3)}</div>`
const [series1, series2] = params
const [channel, energy1] = series1.value
let html = `<div class="channel">Channel: ${channel}</div>
<div class="energy">Energy: ${energy1.toFixed(3)}</div>`
if (series2) {
const [_, energy2] = series2.value
html += `<div class="warning">Energy: ${energy2}</div>`
}
return html
},
className: 'figure-chart-option-tooltip'
},
@ -431,22 +457,40 @@ const initialFigureChartOption = {
},
nameGap: 55
},
series: {
type: 'line',
itemStyle: {
color: '#04ADD9'
series: [
{
type: 'line',
itemStyle: {
color: '#04ADD9'
},
symbol: 'none',
data: [],
markPoint: {
symbol: 'circle',
symbolSize: 8,
data: []
}
},
symbol: 'none',
data: []
}
{
type: 'line',
itemStyle: {
color: 'yellow'
},
symbol: 'none',
data: [],
markPoint: {
symbol: 'circle',
symbolSize: 8,
data: []
}
}
]
}
const columns = [
{
title: 'Index',
customRender: (_, __, index) => {
return index + 1
},
dataIndex: 'rowCount',
align: 'center'
},
{
@ -457,16 +501,19 @@ const columns = [
{
title: 'Energy/keV',
dataIndex: 'energy',
align: 'center'
align: 'center',
customRender: (text) => {
return text.toPrecision(6)
}
},
{
title: 'FWHM/C',
dataIndex: 'fwhmC',
dataIndex: 'c',
align: 'center'
},
{
title: 'FWHM/keV',
dataIndex: 'fwhmKev',
dataIndex: 'keV',
align: 'center'
},
{
@ -478,6 +525,12 @@ const columns = [
}
]
const newCalibrationFuncModel = {
paramA: '',
paramB: '',
paramC: ''
}
export default {
components: { CustomChart, TitleOverBorder },
props: {
@ -522,7 +575,9 @@ export default {
c2e: {},
e2c: {},
newCalibrationFuncModel: [],
newE2C: [],
newCalibrationFuncModel: cloneDeep(newCalibrationFuncModel),
newCalibrationIsAppliedTo: '2',
recalculateROICountsFor: []
@ -544,9 +599,16 @@ export default {
const res = await getAction('/spectrumAnalysis/viewBetaDetectorCalibration', {
sampleId: this.sampleId
})
console.log('%c [ res ]-462', 'font-size:13px; background:pink; color:#bf2c9f;', res)
if (res.success) {
const { CToE, EToC, betaEnergy, gammaEnergy, gammaGatedBetaSpectrum, histogramData } = res.result
const {
CToE,
EToC,
betaEnergy,
gammaEnergy,
gammaGatedBetaSpectrum,
histogramData,
oldScatterSeries
} = res.result
this.c2e = CToE
this.e2c = EToC
@ -561,7 +623,8 @@ export default {
this.figureChartOption.yAxis.max = gammaEnergyInterval * 4
this.figureChartOption.yAxis.min = gammaEnergyMin
this.figureChartOption.yAxis.interval = Math.ceil((gammaEnergyMax * 1.1) / 4)
this.figureChartOption.series.data = gammaEnergyValue.map((item, index) => [index, item])
this.figureChartOption.series[0].data = gammaEnergyValue.map((item, index) => [index, item])
this.figureChartOption.series[0].markPoint.data = oldScatterSeries.map(({ x, y }) => ({ xAxis: x, yAxis: y }))
} else {
this.$message.error(res.message)
}
@ -665,11 +728,56 @@ export default {
// Reset Button
handleReset() {
this.newCalibrationFuncModel = []
this.newCalibrationFuncModel = cloneDeep(newCalibrationFuncModel)
this.list = []
this.newE2C = []
this.figureChartOption = this.oldChartOption
},
// Fitting
handleFitting() {},
async handleFitting() {
const hasEmpty = Object.entries(this.newCalibrationFuncModel).some(([_, v]) => !v)
if (hasEmpty) {
return
}
try {
const { success, result, message } = await getAction('/spectrumAnalysis/fitting', {
...this.newCalibrationFuncModel,
tempPoints: this.figureChartOption.series[0].markPoint.data.map(item => item.xAxis).join(',')
})
if (success) {
const { EToC, newLineSeries, newScatterSeriesData, tableWidgets } = result
this.newE2C = EToC
this.list = tableWidgets
this.oldChartOption = cloneDeep(this.figureChartOption)
const energyValues = newLineSeries.map(item => item.y)
const { max: prevMax, min: prevMin } = this.figureChartOption.yAxis
const energyMax = Math.max(Math.max(...energyValues), prevMax)
const energyMin = Math.min(Math.min(...energyValues), prevMin)
const energyInterval = Math.ceil(((energyMax - energyMin) / 4) * 1.1)
this.figureChartOption.yAxis.max = energyInterval * 4
this.figureChartOption.yAxis.min = energyMin
this.figureChartOption.yAxis.interval = Math.ceil((energyMax * 1.1) / 4)
this.figureChartOption.series[1].data = newLineSeries.map(({ x, y }) => [x, y])
this.figureChartOption.series[1].markPoint.data = newScatterSeriesData.map(({ x, y }) => {
return {
xAxis: x,
yAxis: y
}
})
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
}
},
/**
* 返回的科学计数法的字符串处理
@ -682,7 +790,7 @@ export default {
const end = arr[1]
return `${Number(start).toPrecision(6)}${end ? 'e' + end : ''}`
}
return ''
return 0
}
},
computed: {

View File

@ -37,6 +37,7 @@
</a-form-model>
<a-button type="primary" @click="handleAddChannelAndEnergy">Add</a-button>
</div>
<!-- 表格开始 -->
<a-table
size="small"
:columns="columns"
@ -49,6 +50,7 @@
<a-icon type="delete" style="color: #f00;" @click="handleDel(index)"></a-icon>
</template>
</a-table>
<!-- 表格结束 -->
</div>
<div class="figure">
<p class="title">Figure of Gamma Detector Calibration</p>
@ -87,14 +89,17 @@
<span>C to E : </span>
<span>
E =
<a-input type="number" size="small" v-model="newCalibrationFuncModel[0]" /> +
<a-input type="number" size="small" v-model="newCalibrationFuncModel[1]" /> *C +
<a-input type="number" size="small" v-model="newCalibrationFuncModel[2]" /> *C <sup>2</sup>
<a-input type="number" size="small" v-model="newCalibrationFuncModel.paramA" /> +
<a-input type="number" size="small" v-model="newCalibrationFuncModel.paramB" /> *C +
<a-input type="number" size="small" v-model="newCalibrationFuncModel.paramC" /> *C <sup>2</sup>
</span>
</p>
<div class="func">
<span>E to C : </span>
<span>C = 0 + 0 *E + 0 *E <sup>2</sup> </span>
<span
>C = {{ scientificNotationStr2Fixed(newE2C[0]) }} + {{ scientificNotationStr2Fixed(newE2C[1]) }} *E
+ {{ scientificNotationStr2Fixed(newE2C[2]) }} *E <sup>2</sup>
</span>
</div>
</title-over-border>
</div>
@ -270,9 +275,18 @@ const initialFigureChartOption = {
}
},
formatter: params => {
const [channel, energy] = params[0].value
return `<div class="channel">Channel: ${channel}</div>
<div class="energy">Energy: ${energy.toFixed(3)}</div>`
const [series1, series2] = params
const [channel, energy1] = series1.value
let html = `<div class="channel">Channel: ${channel}</div>
<div class="energy">Energy: ${energy1.toFixed(3)}</div>`
if (series2) {
const [_, energy2] = series2.value
html += `<div class="warning">Energy: ${energy2}</div>`
}
return html
},
className: 'figure-chart-option-tooltip'
},
@ -342,16 +356,25 @@ const initialFigureChartOption = {
color: '#04ADD9'
},
symbol: 'none',
data: []
data: [],
markPoint: {
symbol: 'circle',
symbolSize: 8,
data: []
}
},
{
type: 'line',
itemStyle: {
color: '#04ADD9'
color: 'yellow'
},
symbol: 'circle',
symbolSize: 8,
data: []
symbol: 'none',
data: [],
markPoint: {
symbol: 'circle',
symbolSize: 8,
data: []
}
}
]
}
@ -359,9 +382,7 @@ const initialFigureChartOption = {
const columns = [
{
title: 'Index',
customRender: (_, __, index) => {
return index + 1
},
dataIndex: 'rowCount',
align: 'center'
},
{
@ -372,16 +393,19 @@ const columns = [
{
title: 'Energy/keV',
dataIndex: 'energy',
align: 'center'
align: 'center',
customRender: (text) => {
return text.toPrecision(6)
}
},
{
title: 'FWHM/C',
dataIndex: 'fwhmC',
dataIndex: 'c',
align: 'center'
},
{
title: 'FWHM/keV',
dataIndex: 'fwhmKev',
dataIndex: 'keV',
align: 'center'
},
{
@ -393,6 +417,12 @@ const columns = [
}
]
const newCalibrationFuncModel = {
paramA: '',
paramB: '',
paramC: ''
}
export default {
components: { CustomChart, TitleOverBorder },
props: {
@ -408,8 +438,10 @@ export default {
figureChartOption: cloneDeep(initialFigureChartOption),
list: [],
isLoading: false,
c2e: {},
e2c: {},
c2e: [],
e2c: [],
newE2C: [],
tooltipVisible: false,
tooltipPosition: {
@ -420,7 +452,7 @@ export default {
channelAndEnergyModel: {},
newCalibrationFuncModel: [],
newCalibrationFuncModel: cloneDeep(newCalibrationFuncModel),
newCalibrationIsAppliedTo: '2',
recalculateROICountsFor: []
@ -463,7 +495,7 @@ export default {
this.figureChartOption.yAxis.min = gammaEnergyMin
this.figureChartOption.yAxis.interval = Math.ceil((gammaEnergyMax * 1.1) / 4)
this.figureChartOption.series[0].data = gammaEnergyValue.map((item, index) => [index, item])
this.figureChartOption.series[1].data = oldScatterSeries.map(({ x, y }) => [x, y])
this.figureChartOption.series[0].markPoint.data = oldScatterSeries.map(({ x, y }) => ({ xAxis: x, yAxis: y }))
} else {
this.$message.error(res.message)
}
@ -526,11 +558,56 @@ export default {
// Reset Button
handleReset() {
this.newCalibrationFuncModel = []
this.newCalibrationFuncModel = cloneDeep(newCalibrationFuncModel)
this.list = []
this.newE2C = []
this.figureChartOption = this.oldChartOption
},
// Fitting
handleFitting() {},
async handleFitting() {
const hasEmpty = Object.entries(this.newCalibrationFuncModel).some(([_, v]) => !v)
if (hasEmpty) {
return
}
try {
const { success, result, message } = await getAction('/spectrumAnalysis/fitting', {
...this.newCalibrationFuncModel,
tempPoints: this.figureChartOption.series[0].markPoint.data.map(item => item.xAxis).join(',')
})
if (success) {
const { EToC, newLineSeries, newScatterSeriesData, tableWidgets } = result
this.newE2C = EToC
this.list = tableWidgets
this.oldChartOption = cloneDeep(this.figureChartOption)
const energyValues = newLineSeries.map(item => item.y)
const { max: prevMax, min: prevMin } = this.figureChartOption.yAxis
const energyMax = Math.max(Math.max(...energyValues), prevMax)
const energyMin = Math.min(Math.min(...energyValues), prevMin)
const energyInterval = Math.ceil(((energyMax - energyMin) / 4) * 1.1)
this.figureChartOption.yAxis.max = energyInterval * 4
this.figureChartOption.yAxis.min = energyMin
this.figureChartOption.yAxis.interval = Math.ceil((energyMax * 1.1) / 4)
this.figureChartOption.series[1].data = newLineSeries.map(({ x, y }) => [x, y])
this.figureChartOption.series[1].markPoint.data = newScatterSeriesData.map(({ x, y }) => {
return {
xAxis: x,
yAxis: y
}
})
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
}
},
/**
* 返回的科学计数法的字符串处理
@ -543,7 +620,7 @@ export default {
const end = arr[1]
return `${Number(start).toPrecision(6)}${end ? 'e' + end : ''}`
}
return ''
return 0
}
}
}
@ -734,5 +811,9 @@ p {
.energy {
color: #00d1f0;
}
.warning {
color: yellow;
}
}
</style>