feat: 完成Fitting功能
This commit is contained in:
		
							parent
							
								
									6456b949e7
								
							
						
					
					
						commit
						8f019687a4
					
				|  | @ -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: { | ||||
|  |  | |||
|  | @ -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> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user