From 944e1b2398b3031a36307da3fad2a6c2bbf142cc Mon Sep 17 00:00:00 2001 From: xiaoguangbin Date: Wed, 11 Sep 2024 15:59:54 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E6=96=B0beta=E8=B0=B1=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=A4=84=E7=90=86=20beta=E5=88=86=E6=9E=90=E3=80=81?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=AD=98=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jeecg/common/util/SelfStationUtil.java | 815 ++++++++++++++++++ .../modules/entity/vo/SelfXeResults.java | 36 + .../struct/SelfBgAnalyseResult.java | 26 + 3 files changed, 877 insertions(+) create mode 100644 jeecg-module-beta-gamma-analyser/src/main/java/org/jeecg/common/util/SelfStationUtil.java create mode 100644 jeecg-module-beta-gamma-analyser/src/main/java/org/jeecg/modules/entity/vo/SelfXeResults.java create mode 100644 jeecg-module-beta-gamma-analyser/src/main/java/org/jeecg/modules/native_jni/struct/SelfBgAnalyseResult.java diff --git a/jeecg-module-beta-gamma-analyser/src/main/java/org/jeecg/common/util/SelfStationUtil.java b/jeecg-module-beta-gamma-analyser/src/main/java/org/jeecg/common/util/SelfStationUtil.java new file mode 100644 index 00000000..1902a8ac --- /dev/null +++ b/jeecg-module-beta-gamma-analyser/src/main/java/org/jeecg/common/util/SelfStationUtil.java @@ -0,0 +1,815 @@ +package org.jeecg.common.util; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.IORuntimeException; +import cn.hutool.core.lang.Console; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.common.cache.Cache; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.constant.RedisConstant; +import org.jeecg.modules.base.abstracts.AbstractLogOrReport; +import org.jeecg.modules.base.enums.CalName; +import org.jeecg.modules.base.enums.DataTypeAbbr; +import org.jeecg.modules.base.enums.SampleFileHeader; +import org.jeecg.modules.entity.vo.*; +import org.jeecg.modules.native_jni.CalValuesHandler; +import org.jeecg.modules.native_jni.EnergySpectrumHandler; +import org.jeecg.modules.native_jni.struct.BgBoundary; +import org.jeecg.modules.native_jni.struct.CalValuesOut; +import org.jeecg.modules.native_jni.struct.CalcBgBoundaryParam; +import org.jeecg.modules.native_jni.struct.EnergySpectrumStruct; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.io.*; +import java.text.DecimalFormat; +import java.text.ParseException; +import java.util.*; +import java.util.stream.Collectors; + +@Component +@Slf4j +public class SelfStationUtil extends AbstractLogOrReport { + + @Autowired + private FTPUtil ftpUtil; + + + /** + * 解析 #histogram块数据 + * @param phdPath 文件地址 + * @return + */ + public HashMap readPHDFile(String phdPath) { + try { + File file = new File(phdPath); + HashMap result = Maps.newHashMap(); + BufferedReader reader = FileUtil.getReader(file, "utf8"); + List hCounts = Lists.newLinkedList(); + String currentName = ""; + long [][] hCountArr = null; + int row = 0; + String blockHis = SampleFileHeader.HISTOGRAM.getMessage(); + while (reader.ready()) { + // 当前行 + String line = reader.readLine(); + if (line.equals(blockHis)) { + currentName = line; + // 首行 + String s = reader.readLine(); + String[] split = s.split(" "); + hCountArr = new long[Integer.parseInt(split[0])][Integer.parseInt(split[1])]; + result.put("g_channels", Long.parseLong(split[0])); + result.put("b_channels", Long.parseLong(split[1])); + result.put("g_energy_span", Long.parseLong(split[2])); + result.put("b_energy_span", Long.parseLong(split[3])); + Console.log(s); + continue; + } + if (!line.equals(blockHis) && !currentName.equals(blockHis)) { + continue; + } + if (line.equals("STOP")) { + break; + } + String[] split = line.split(" "); + for (int i = 0; i < split.length; i++) { + hCountArr[row][i] = Long.parseLong(split[i]); + hCounts.add(Long.parseLong(split[i])); + } + row++; + } + result.put("h_count", hCountArr); + Console.log("Size:{}",hCounts.size()); + return result; + } catch (IORuntimeException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } catch (NumberFormatException e) { + throw new RuntimeException(e); + } + } + /** + * 统计道值范围内数量 + * @param startChannel 起始道值 + * @param endChannel 结束道值 + * @param betaChannels 行数 + * @param gammaChannels 列数 + * @param h_counts 计数数组 + */ + public Map statisticsROIList(Integer startChannel, Integer endChannel, long betaChannels, long gammaChannels, List h_counts) { + Map map = new HashMap<>(); + // g_counts + List counts = new LinkedList<>(); + //存储同一列不同行加和后的数量 + List sumList = new LinkedList<>(); + List seriseDataList = new LinkedList<>(); + //遍历所有列 + for (int i=0; i 0 && index < h_counts.size()) { + count = h_counts.get(index); + } + sum+=count; + } + seriseData.setY(sum); + sumList.add(sum); + counts.add((long) sum); + seriseDataList.add(seriseData); + } + map.put("startChannel", startChannel); + map.put("endChannel", endChannel); + map.put("dataList", seriseDataList); + map.put("counts", counts); + Console.log(counts.toString()); + return map; + } + + + public List roiList(Integer startChannel, Integer endChannel, long betaChannels, long gammaChannels, List h_counts) { + // g_counts + List counts = new LinkedList<>(); + //存储同一列不同行加和后的数量 + List sumList = new LinkedList<>(); + //遍历所有列 + for (int i=0; i 0 && index < h_counts.size()) { + count = h_counts.get(index); + } + sum+=count; + } + counts.add(sum); + } + return counts; + } + + public String UpdateEquationEnergy(ParameterInfo m_curParam) { + String equation =""; + int p_size = m_curParam.getP().size()-1; + if(p_size >= 2 && m_curParam.getP().get(2) > 0) { + // Polynomial: y=a0+a1*x+a2*x^2+a3*x^3 + equation +="Energy = "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(1)))+" + C * "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(2))); + for(int i=3; i<=p_size; i++) { + equation += " + C" + (i-1) +" * "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(i)))+""; + } + } else if(p_size == 1) { + equation = "Energy = "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(1)))+" * C"; + } + return equation; + } + + public String UpdateEquationResolution(ParameterInfo m_curParam) { + String equation = ""; + int p_size = m_curParam.getP().size()-1; + if(p_size >= 2 && m_curParam.getP().get(1) > 0 && m_curParam.getP().get(2) > 0) { + // Square root of polynomial: y = sqrt(a0+a1*x+a2*x^2+a3*x^3 ) + equation += "FWHM = ("+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(1)))+" + E * "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(2))); + for(int i=3; i<=p_size; i++) { + equation += " + E"+(i-1)+" * "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(i))); + } + equation += ")"+1+"/"+2+""; + } + return equation; + } + + public String UpdateEquationEfficiency(List m_vCurEnergy, ParameterInfo m_curParam, Integer curRow, Integer funId) { + String equation = ""; + if(m_curParam.getP().size() > 2) { + int p_size = m_curParam.getP().size()-1; + int e_size = m_vCurEnergy.size(); + if (Objects.isNull(funId)) { + funId = m_curParam.getP().get(0).intValue(); + } + switch(funId) { + case 1: // Interpolation: y=yi+(y(i+1)-yi)*(x-xi)/(x(i+1)-xi) for xi<=x= 4) { + int i = curRow; + if(i < 0 || i >= e_size) break; + + double y1, y0, x1, x0; + if(i < e_size - 1) + { + y1 = Double.valueOf(NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(i*2+3)))); + y0 = Double.valueOf(NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(i*2+1)))); + x1 = Double.valueOf(NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(i*2+2)))); + x0 = Double.valueOf(NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(i*2)))); + } else { + y1 = Double.valueOf(NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(i*2+1)))); + y0 = Double.valueOf(NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(i*2-1)))); + x1 = Double.valueOf(NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(i*2)))); + x0 = Double.valueOf(NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(i*2-2)))); + } + equation += "Efficiency = "+y0+" + ("+y1+"-"+y0+") * (E - "+x0+") / ("+x1+" - "+x0+")"; + } + break; + case 5: // HT Efficiency: y = A*exp(-(E1/x)^k)*(1-exp(-(E2/x)^n)) + if(p_size == 5) { + for(int i=1; i<=p_size; i++) { + if(m_curParam.getP().get(i) <= 0) break; + } + equation += "Efficiency = "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(1)))+" * exp(-("+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(2)))+" / E)"+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(3)))+") * "+ + "(1-exp(-("+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(4)))+" / E)"+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(5)))+"))"; + } + break; + case 6: // Polynomial in log(y) against log(x): log(y) = a0 + a1*log(x) +a2*log(x)^2+ a3*log(x)^3 + if(p_size >= 2) { + equation += "log(Efficiency) = "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(1)))+" + "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(2)))+" * log(E)"; + for(int i=3; i<=p_size; i++) { + equation += " + "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(i)))+" * log(E)"+(i-1)+""; + } + } + break; + case 8: // Polynomial in log(y) against log(1/x): log(y) = a0 + a1*log(c/x) + a2*log(c/x)^2 + a3*log(c/x)^3 + a4*log(c/x)^4 + if(p_size >= 3) { + equation += "log(Efficiency) = "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(1)))+" + "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(2)))+" * log(C/E)"; + for(int i=3; i<=p_size; i++) { + equation += " + "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(i)))+" * log(C/E)"+(i-1)+""; + } + } + break; + case 93: // HAE Efficiency (1-3): y=S*exp(-(E1/x)^k)*(1- exp(-(2*E3/(x-E3))^n)) + if(p_size == 5) { + equation += "Efficiency = "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(1)))+" * exp(-("+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(2)))+" / E)"+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(3)))+") * "+ + "(1 - exp(-(2 * "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(4)))+" / (E - "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(4)))+"))"+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(5)))+"))"; + } + break; + case 94: // HAE Efficiency (1-2): y=S*exp(-(E1/x)^k)*(1- exp(-b*(1/(x-E2))^m)) + if(p_size == 6) { + equation += "Efficiency = "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(1)))+" * exp(-("+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(2)))+" / E)"+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(3)))+") * "+ + "(1 - exp(-"+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(4)))+" * (1 / (E - "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(5)))+"))"+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(6)))+"))"; + } + break; + case 95: // HAE Efficiency (1-2-3): y = S * exp(-(E1/x)^k) * (1- exp(-b*(1/(x-E2))^m)) *(1 - exp(-(2*E3/(E-E3))^n)) + if(p_size == 8) { + equation += "Efficiency = "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(1)))+" * exp(-("+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(2)))+" / E)"+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(3)))+") * "+ + "(1 - exp(-"+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(4)))+" * (1 / (E - "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(5)))+"))"+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(6)))+")) * "+ + "(1 - exp(-(2 * "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(7)))+" / (E - "+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(7)))+"))"+NumberFormatUtil.numberFormat(String.valueOf(m_curParam.getP().get(8)))+"))"; + } + break; + } + } + return equation; + } + + /** + * 根据ROI卡出来的Gamma数据生成新的GammaPHD文件 + * @param pathName 文件存储路径 + * @param fileName GammaPHD名称 + * @param struct BetaPHD内容 + * @param g_counts ROI卡出来的Gamma数据 + */ + public static void createGammaFile(String pathName,String fileName, EnergySpectrumStruct struct, List g_counts) { + File file = new File(pathName + "\\" + fileName); + // 创建PrintWriter对象 + PrintWriter out = null; + DecimalFormat decimalFormat = new DecimalFormat("0.000000"); + try { + out = new PrintWriter(file); + out.println("BEGIN IMS2.0"); + out.println("MSG_TYPE DATA"); + // todo msg_type用的不对,dll没解析出这个字段 + out.println("MSG_ID " + struct.msg_id + " " + struct.msg_type + "\n" + "DATA_TYPE " + struct.data_type); + out.println("#Header 3"); + // 解析出的Gamma谱 系统类型暂时使用G + out.println(struct.site_code + " " + struct.detector_code + " G " + + struct.sample_geometry + " " + struct.spectrum_quantity); + out.println(struct.sample_ref_id); + out.println(struct.measurement_id + " " + struct.detector_bk_measurement_id + " 0"); + out.println(struct.transmit_date + " " + struct.transmit_time); + out.println("#Collection"); + out.println(struct.collection_start_date + " " + struct.collection_start_time + " " + + struct.collection_stop_date + " " + struct.collection_stop_time + " " + + decimalFormat.format(struct.air_volume)); + out.println("#Acquisition"); + out.println(struct.acquisition_start_date + " " + struct.acquisition_start_time + " " + + decimalFormat.format(struct.acquisition_real_time) + " " + + decimalFormat.format(struct.acquisition_live_time)); + out.println("#g_Energy"); + + + format(struct.g_energy, struct.g_centroid_channel, struct.g_uncertainty, out); + out.println("#g_Resolution"); + format(struct.g_r_energy, struct.g_r_FWHM, struct.g_r_uncertainty, out); + out.println("#g_Efficiency"); + format(struct.g_e_energy, struct.g_e_efficiency, struct.g_e_uncertainty, out); + out.println("#g_Spectrum"); + // num_g_channel 根据g_counts数量得来和PHD写的数字没有关系;g_energy_span是PHD写的值 + out.println(struct.num_g_channel + " " + struct.g_energy_span); + // 存储前一个数字 + String beforeStr = ""; + for (int i = 0; i < g_counts.size(); i++) { + String str = g_counts.get(i).toString(); + if(i % 5 == 0) { + if (i == 0) { + out.printf((i+1)+""); + } else { + out.printf("\n" + (i+1) ); + } + beforeStr = i+""; + } + + if(StrUtil.isEmpty(beforeStr)){ + beforeStr = str; + } + // 根据前一个字符长度计算需要的空格 + out.printf("%" + (str.length() + (6 - beforeStr.length()))+ "s" , g_counts.get(i)); + if(i == g_counts.size() - 1) { + out.println(); + } + beforeStr = str; + } + out.print("STOP"); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } finally { + if (null != out) { + out.close(); + } + } + } + + /** + * 根据DLL解析GammaPHD内容 得到PHDFile实体 + * @param struct dll解析后的实体 + * @param fileName 文件名称 + * @param pathName 路径 + * @param g_counts beta卡出来的gamma数据 + * @return PHDFile 实体 + */ + public static PHDFile createGammaPHD(EnergySpectrumStruct struct, String fileName, String pathName, List g_counts) { + PHDFile phd = new PHDFile(); + phd.setFilepath(pathName); + phd.setFilename(fileName); + File file = new File(pathName + StringPool.SLASH + fileName); + phd.setTmpFilePath(file.getAbsolutePath()); + try { + //MsgInfo + phd.getMsgInfo().setMsg_id(struct.msg_id); + phd.getMsgInfo().setMsg_type(struct.msg_type); + phd.getMsgInfo().setData_type(struct.data_type); + //Header + phd.getHeader().setDesignator(struct.designator); + phd.getHeader().setSite_code(struct.site_code); + phd.getHeader().setDetector_code(struct.detector_code); + phd.getHeader().setSystem_type(struct.system_type); + phd.getHeader().setSample_geometry(struct.sample_geometry); + phd.getHeader().setSpectrum_quantity(struct.spectrum_quantity); + phd.getHeader().setSample_ref_id(struct.sample_ref_id); + phd.getHeader().setMeasurement_id(struct.measurement_id); + phd.getHeader().setDetector_bk_measurement_id(struct.detector_bk_measurement_id); + phd.getHeader().setGas_bk_measurement_id(struct.gas_bk_measurement_id); + phd.getHeader().setTransmit_date(struct.transmit_date); + phd.getHeader().setTransmit_time(struct.transmit_time); + //Comment + phd.setOriTotalCmt(struct.comment); + //Collection + if (StrUtil.isNotBlank(struct.collection_start_date) && StrUtil.isNotBlank(struct.collection_start_time) + && StrUtil.isNotBlank(struct.collection_stop_date) && StrUtil.isNotBlank(struct.collection_stop_time) + && Objects.nonNull(struct.air_volume)) { + phd.getCollect().setCollection_start_date(struct.collection_start_date); + phd.getCollect().setCollection_start_time(struct.collection_start_time); + phd.getCollect().setCollection_stop_date(struct.collection_stop_date); + phd.getCollect().setCollection_stop_time(struct.collection_stop_time); + phd.getCollect().setAir_volume(struct.air_volume); + if (phd.getCollect().getCollection_start_time().indexOf('.') < 0) { + phd.getCollect().setCollection_start_time(phd.getCollect().getCollection_start_time() + ".0"); + } + if (phd.getCollect().getCollection_stop_time().indexOf('.') < 0) { + phd.getCollect().setCollection_stop_time(phd.getCollect().getCollection_stop_time() + ".0"); + } + } else { + phd.getCollect().setAir_volume(0.0); + } + //Acquisition + if (StrUtil.isNotBlank(struct.acquisition_start_date) && StrUtil.isNotBlank(struct.acquisition_start_time) + && Objects.nonNull(struct.acquisition_real_time) && Objects.nonNull(struct.acquisition_live_time)) { + phd.getAcq().setAcquisition_start_date(struct.acquisition_start_date); + phd.getAcq().setAcquisition_start_time(struct.acquisition_start_time); + phd.getAcq().setAcquisition_real_time(struct.acquisition_real_time); + phd.getAcq().setAcquisition_live_time(struct.acquisition_live_time); + if (phd.getAcq().getAcquisition_start_time().indexOf('.') < 0) { + phd.getAcq().setAcquisition_start_time(phd.getAcq().getAcquisition_start_time() + ".0"); + } + } else { + phd.getAcq().setAcquisition_live_time(0.0); + phd.getAcq().setAcquisition_real_time(0.0); + } + //Processing + if (Objects.nonNull(struct.sample_volume_of_Xe) && Objects.nonNull(struct.uncertainty_1) + && Objects.nonNull(struct.Xe_collection_yield) && Objects.nonNull(struct.uncertainty_2) + && StrUtil.isNotBlank(struct.archive_bottle_id)) { + phd.getProcess().setSample_volume_of_Xe(struct.sample_volume_of_Xe); + phd.getProcess().setUncertainty_1(struct.uncertainty_1); + phd.getProcess().setXe_collection_yield(struct.Xe_collection_yield); + phd.getProcess().setUncertainty_2(struct.uncertainty_2); + phd.getProcess().setArchive_bottle_id(struct.archive_bottle_id); + } else { + phd.getProcess().setSample_volume_of_Xe(0.0); + phd.getProcess().setXe_collection_yield(0.0); + phd.getProcess().setUncertainty_1(0.0); + phd.getProcess().setUncertainty_2(0.0); + } + //Sample + if (Objects.nonNull(struct.dimension_1) && Objects.nonNull(struct.dimension_2)) { + phd.getSampleBlock().setDimension_1(struct.dimension_1); + phd.getSampleBlock().setDimension_2(struct.dimension_2); + } else { + phd.getSampleBlock().setDimension_1(0.0); + phd.getSampleBlock().setDimension_2(0.0); + } + //Calibration + if (StrUtil.isNotBlank(struct.date_calibration) && StrUtil.isNotBlank(struct.time_calibration)) { + phd.getCalibration().setDate_calibration(struct.date_calibration); + phd.getCalibration().setTime_calibration(struct.time_calibration); + } + //Certificate + if (Objects.nonNull(struct.total_source_activity) && StrUtil.isNotBlank(struct.assay_date) + && StrUtil.isNotBlank(struct.assay_time) && StrUtil.isNotBlank(struct.units_activity) + && CollectionUtils.isNotEmpty(struct.nuclide_name) + && CollectionUtils.isNotEmpty(struct.half_life_time) && CollectionUtils.isNotEmpty(struct.time_unit) + && CollectionUtils.isNotEmpty(struct.activity_nuclide_time_assay) && CollectionUtils.isNotEmpty(struct.uncertainty) + && CollectionUtils.isNotEmpty(struct.cer_g_energy) && CollectionUtils.isNotEmpty(struct.g_intensity) + && CollectionUtils.isNotEmpty(struct.electron_decay_mode) && CollectionUtils.isNotEmpty(struct.maximum_energy) + && CollectionUtils.isNotEmpty(struct.intensity_b_particle) && Objects.nonNull(struct.record_count)) { + phd.getCertificate().setTotal_source_activity(struct.total_source_activity); + phd.getCertificate().setAssay_date(struct.assay_date); + phd.getCertificate().setAssay_time(struct.assay_time); + phd.getCertificate().setUnits_activity(struct.units_activity); + phd.getCertificate().setNuclide_name(struct.nuclide_name); + phd.getCertificate().setHalf_life_time(struct.half_life_time); + phd.getCertificate().setTime_unit(struct.time_unit); + phd.getCertificate().setActivity_nuclide_time_assay(struct.activity_nuclide_time_assay); + phd.getCertificate().setUncertainty(struct.uncertainty); + phd.getCertificate().setG_energy(struct.cer_g_energy); + phd.getCertificate().setG_intensity(struct.g_intensity); + phd.getCertificate().setElectron_decay_mode(struct.electron_decay_mode); + phd.getCertificate().setMaximum_energy(struct.maximum_energy); + phd.getCertificate().setIntensity_b_particle(struct.intensity_b_particle); + phd.getCertificate().setRecord_count(struct.record_count); + } + //g_Spectrum + if (Objects.nonNull(struct.num_g_channel) && Objects.nonNull(struct.g_energy_span) + && Objects.nonNull(struct.g_begin_channel) && CollectionUtils.isNotEmpty(struct.g_counts)) { + phd.getSpec().setNum_g_channel(struct.g_counts.size()); // todo 原Num_g_channel有误 + phd.getSpec().setG_energy_span(struct.g_energy_span); + phd.getSpec().setBegin_channel(struct.g_begin_channel); + // 从 struct.g_counts 换成 beta 卡出来的gamma数据 + phd.getSpec().setCounts(g_counts); + int i = 0; + for (; i < phd.getSpec().getNum_g_channel(); i++) { + if (phd.getSpec().getCounts().get(i) > 0) { + break; + } + } + if (i == phd.getSpec().getNum_g_channel()) { + phd.setValid(false); + } + } + //g_Energy + if (CollectionUtils.isNotEmpty(struct.g_energy) && CollectionUtils.isNotEmpty(struct.g_centroid_channel) && + CollectionUtils.isNotEmpty(struct.g_uncertainty) && Objects.nonNull(struct.g_record_count)) { + GEnergyBlock gEnergyBlock = new GEnergyBlock(); + gEnergyBlock.setG_energy(struct.g_energy); + gEnergyBlock.setCentroid_channel(struct.g_centroid_channel); + gEnergyBlock.setUncertainty(struct.g_uncertainty); + gEnergyBlock.setRecord_count(struct.g_record_count); + phd.getMapEnerKD().put(CalName.CalPHD.getType(), gEnergyBlock); + } + //g_Resolution + if (CollectionUtils.isNotEmpty(struct.g_r_energy) && CollectionUtils.isNotEmpty(struct.g_r_FWHM) && + CollectionUtils.isNotEmpty(struct.g_r_uncertainty) && Objects.nonNull(struct.g_r_record_count)) { + GResolutionBlock gResolutionBlock = new GResolutionBlock(); + gResolutionBlock.setG_energy(struct.g_r_energy); + gResolutionBlock.setFWHM(struct.g_r_FWHM); + gResolutionBlock.setUncertainty(struct.g_r_uncertainty); + gResolutionBlock.setRecord_count(struct.g_r_record_count); + phd.getMapResoKD().put(CalName.CalPHD.getType(), gResolutionBlock); + } + //g_Efficiency + if (CollectionUtils.isNotEmpty(struct.g_e_energy) && CollectionUtils.isNotEmpty(struct.g_e_efficiency) && + CollectionUtils.isNotEmpty(struct.g_e_uncertainty) && Objects.nonNull(struct.g_e_record_count)) { + GEfficiencyBlock gEfficiencyBlock = new GEfficiencyBlock(); + gEfficiencyBlock.setG_energy(struct.g_e_energy); + gEfficiencyBlock.setEfficiency(struct.g_e_efficiency); + gEfficiencyBlock.setUncertainty(struct.g_e_uncertainty); + gEfficiencyBlock.setRecord_count(struct.g_e_record_count); + phd.getMapEffiKD().put(CalName.CalPHD.getType(), gEfficiencyBlock); + } + //TotalEff + if (CollectionUtils.isNotEmpty(struct.t_g_energy) && CollectionUtils.isNotEmpty(struct.total_efficiency) && + CollectionUtils.isNotEmpty(struct.t_uncertainty) && Objects.nonNull(struct.t_record_count)) { + TotaleffBlock totaleffBlock = new TotaleffBlock(); + totaleffBlock.setG_energy(struct.t_g_energy); + totaleffBlock.setTotal_efficiency(struct.total_efficiency); + totaleffBlock.setUncertainty(struct.t_uncertainty); + totaleffBlock.setRecord_count(struct.t_record_count); + phd.getMapTotEKD().put(CalName.CalPHD.getType(), totaleffBlock); + } + + // 初始化默认分析设置 + if(phd.getHeader().getSystem_type().equalsIgnoreCase("P")) { + phd.getSetting().setECutAnalysis_Low(35.0); + phd.getSetting().setBUpdateCal(true); + } + if (StrUtil.isNotBlank(phd.getCollect().getCollection_start_date()) + && StrUtil.isNotBlank(phd.getCollect().getCollection_start_time())) { + phd.getSetting().setRefTime_conc(DateUtils.parseDate(phd.getCollect().getCollection_start_date() + + StringPool.SPACE + phd.getCollect().getCollection_start_time())); + } + if (StrUtil.isNotBlank(phd.getAcq().getAcquisition_start_date()) && StrUtil.isNotBlank(phd.getAcq().getAcquisition_start_time())) { + phd.getSetting().setRefTime_act(DateUtils.parseDate(phd.getAcq().getAcquisition_start_date() + + StringPool.SPACE + phd.getAcq().getAcquisition_start_time())); + } + SpecSetup usedSetting = new SpecSetup(); + BeanUtils.copyProperties(phd.getSetting(), usedSetting); + phd.setUsedSetting(usedSetting); + + phd.setBAnalyed(false); + phd.setAnaly_start_time(DateUtils.formatDate(new Date(), "yyyy/MM/dd HH:mm:ss")); + + } catch (Exception e) { + throw new RuntimeException(e); + } + return phd; + } + + /** + * 数据格式化 + * @param aList 第一列数据 + * @param bList 第二列数据 + * @param cList 第三列数据 + * @param out + */ + private static void format(List aList, List bList,List cList,PrintWriter out) { + for (int i = 0; i < aList.size(); i++) { + DecimalFormat decimalFormat = new DecimalFormat("0.000000"); + String a = decimalFormat.format(aList.get(i)); + String b = decimalFormat.format(bList.get(i)); + String c = decimalFormat.format(cList.get(i)); + out.print(a); + out.printf("%" + ( b.length() + (17 - a.length())) + "s", b); + out.printf("%" + ( c.length() + (17 - b.length())) + "s", c+"\n"); + } + } + + public HashMap DetailedInfo(Integer sampleId, String status, EnergySpectrumStruct struct) { + try { + HashMap detailedMap = Maps.newHashMap(); + //Data Type + String dataType = struct.data_type; + //Collection Start + Date CollectionStart = null; + if ( StringUtils.isNotBlank(struct.collection_start_date) && StringUtils.isNotBlank(struct.collection_start_time) ){ + CollectionStart = DateUtils.parseDate(struct.collection_start_date + StringPool.SPACE + struct.collection_start_time); + } + //Collection Stop + Date CollectionStop = null; + if ( StringUtils.isNotBlank(struct.collection_stop_date) && StringUtils.isNotBlank(struct.collection_stop_time) ){ + CollectionStop = DateUtils.parseDate(struct.collection_stop_date + StringPool.SPACE + struct.collection_stop_time); + } + //Collection Time + String CollectionTime = ""; + if ( Objects.nonNull(CollectionStart) && Objects.nonNull(CollectionStop) ){ + CollectionTime = String.format ("%.2f",Double.valueOf((CollectionStop.getTime() - CollectionStart.getTime())/ 1000)); + } + //Acquisition Start + Date AcquisitionStart = null; + if ( StringUtils.isNotBlank(struct.acquisition_start_date) && StringUtils.isNotBlank(struct.acquisition_start_time) ){ + AcquisitionStart = DateUtils.parseDate(struct.acquisition_start_date + StringPool.SPACE + struct.acquisition_start_time); + } + //Acq Real Time + double AcquisitionRealTime = struct.acquisition_real_time; + //Acq live Time + double AcquisitionLiveTime = struct.acquisition_live_time; + //Air Volume[m3] + double airVolume = struct.air_volume; + //Xe Volume[m3] + double xeVolume = struct.sample_volume_of_Xe; + //xeCollectionYield + double xeCollectionYield = struct.Xe_collection_yield; + //gasBkMeasurementId + String gasBkMeasurementId = struct.gas_bk_measurement_id; + //detectorBkMeasurementId + String detectorBkMeasurementId = struct.detector_bk_measurement_id; + //measurementId + String measurementId = struct.measurement_id; + detailedMap.put("sampleId", sampleId); + detailedMap.put("stationCode",struct.site_code); + detailedMap.put("detectorCode", struct.detector_code); + detailedMap.put("systemType", struct.system_type); + detailedMap.put("dataType", dataType); + detailedMap.put("spectralQualifier", struct.spectrum_quantity); +// detailedMap.put("SRID", struct.sample_ref_id); + detailedMap.put("status", status); + detailedMap.put("collectionStart", CollectionStart); + detailedMap.put("collectionStop", CollectionStop); + detailedMap.put("collectionTime", CollectionTime); + double timeSpan = 0.0; + if (Objects.nonNull(CollectionStart) && Objects.nonNull(CollectionStop)) { + timeSpan = (CollectionStop.getTime()/1000 - CollectionStart.getTime()/1000) / 3600.0; + } +// detailedMap.put("samplingTime", String.format("%.2f", timeSpan)); + detailedMap.put("airVolume", String.format("%.5f", airVolume)); + detailedMap.put("xeVolume", String.format("%.5f", xeVolume)); + detailedMap.put("yeild", xeCollectionYield); + detailedMap.put("detectorBkMeasurementId", detectorBkMeasurementId); + detailedMap.put("measurementId", measurementId); + detailedMap.put("acquisitionStart", AcquisitionStart); + detailedMap.put("acquisitionRealTime", String.format("%.2f", AcquisitionRealTime)); + detailedMap.put("acquisitionLiveTime", String.format("%.2f", AcquisitionLiveTime)); + double timespan = 0.0; + if (Objects.nonNull(AcquisitionStart) && Objects.nonNull(CollectionStop)) { + timespan = (AcquisitionStart.getTime()/1000 - CollectionStop.getTime()/1000); + } +// detailedMap.put("acquisitionDecayTime", String.format("%.2f", timespan / 3600.0)); + // todo 分级暂时定为1 + detailedMap.put("category", "1"); + detailedMap.put("lat", struct.lat); + detailedMap.put("lon", struct.lon); + return detailedMap; + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + + /** + * beta分析 + * @param selfParameter 自建台站参数 + * @param POI_G_y1 limit gamma + * @param POI_G_y2 limit gamma + * @param betaPhdFile betaPhd文件地址 + * @param gammaPhdFiles gammaPHD + * @throws JsonProcessingException + */ + public static List betaAnalyse(SelfParameter selfParameter, List POI_G_y1, List POI_G_y2, + String betaPhdFile, PHDFile ... gammaPhdFiles) { + + List xeDataList = Lists.newArrayList(); + HashMap nuclideMap = selfParameter.getNuclideMap(); + + // 获取峰面积、半衰期、发射几率 + HashMap nuclideParam = getBetaAnalyseNuclideParam(nuclideMap, POI_G_y1, POI_G_y2, gammaPhdFiles); + Console.log(JSON.toJSONString(nuclideParam)); + // 调用beta分析算法 + String resultStr = EnergySpectrumHandler.selfBgAnalyse(betaPhdFile, JSON.toJSONString(nuclideParam)); + if (StrUtil.isNotBlank(resultStr)) { + xeDataList = JSON.parseArray(resultStr, SelfXeResults.class); + xeDataList.forEach(SelfXeResults::getMdc); + if (CollectionUtils.isNotEmpty(xeDataList)){ + for (SelfXeResults xeData:xeDataList) { + Double conc = xeData.getConc(); + Double mdc = xeData.getMdc(); + if (conc <= 0){ +// xeData.setColor("red"); + xeData.setNidFlag(0); + } else if (0 mdc) { +// xeData.setColor("green"); + xeData.setNidFlag(1); + } + xeData.setMdc(Double.valueOf(NumberFormatUtil.numberSixLen(String.valueOf(xeData.getMdc())))); + xeData.setConc(Double.valueOf(NumberFormatUtil.numberSixLen(String.valueOf(xeData.getConc())))); + xeData.setConcErr(Double.valueOf(NumberFormatUtil.numberSixLen(String.valueOf(xeData.getConcErr())))); + xeData.setMda(Double.valueOf(NumberFormatUtil.numberSixLen(String.valueOf(xeData.getMda())))); + } + } + } + Console.log(resultStr); + return xeDataList; + } + + /** + * 获取结算结果需要的参数(峰面积、半衰期、发射几率) + * @param gStart RoiLimit Gamma Start + * @param gStop RoiLimit Gamma Stop + */ + public static HashMap getBetaAnalyseNuclideParam(HashMap nuclideMap, + List gStart, List gStop, PHDFile ...phdFiles) { + HashMap param = Maps.newHashMap(); + String mapKey = ""; + // 遍历roiLimit + for (int g = 0; g < gStart.size(); g++) { + List vPeak = phdFiles[g].getVPeak();; + HashMap nuclideParam = Maps.newHashMap(); + String nuclideName = ""; + switch (g) { + case 0: + nuclideName = "Xe131M"; + mapKey = "XE-131m"; + break; + case 1: + nuclideName = "Xe133M"; + mapKey = "XE-133m"; + break; + case 2: + nuclideName = "Xe133"; + mapKey = "XE-133"; + break; + case 3: + nuclideName = "Xe135"; + mapKey = "XE-135"; + break; + } + + // 发射几率 + nuclideParam.put("yield", nuclideMap.get(nuclideName).getYield().toString()); + // 半衰期 + nuclideParam.put("halflife", nuclideMap.get(nuclideName).getHalflife().toString()); + // baseline 计数,这里使用的energy是固定的 从配置文件中取出 + nuclideParam.put("baseline", getBetaAnalyseBaseLineCount(phdFiles[g], nuclideName, nuclideMap.get(nuclideName).getEnergy())); + + for (PeakInfo info : vPeak) { + double energy = info.energy; + // 找匹配roi范围的 energy + if (energy > gStart.get(g) && energy < gStop.get(g)) { + double area = info.area; + // 峰如果没有识别到核素则跳过 + if (info.nuclides.contains(nuclideName)) { + // 峰面积 + nuclideParam.put("area", area+""); + break; + } + } + } + // 没有峰信息 核素=未识别 不计算活度浓度 + if (!nuclideParam.containsKey("area")) { + nuclideParam.put("area", "0"); + } + param.put(mapKey, nuclideParam); + } + return param; + } + + /** + * 得到 baseline计数 + * @param phd PHDFile + * @param nuclideName 核素名称 + * @param energy 能量 + * @return + */ + public static double getBetaAnalyseBaseLineCount(PHDFile phd, String nuclideName, Double energy) { + double baseLineCount = 0; + // 得到baseline count范围 + double fwhm = 0; + List vBase = phd.getVBase(); + // fwhm公式参数 + ParameterInfo m_curParam = phd.getMapResoPara().get(phd.getUsedEner()); + // 能量转化道址公式参数 + List userEnerParaP = phd.getUsedEnerPara().getP(); + // 公式参数 + int p_size = m_curParam.getP().size()-1; + if(p_size >= 2 && m_curParam.getP().get(1) > 0 && m_curParam.getP().get(2) > 0) { + fwhm = m_curParam.getP().get(1) + energy * m_curParam.getP().get(2); + for(int i=3; i<=p_size; i++) { + fwhm += (Math.pow(energy, (i-1)) * m_curParam.getP().get(i)); + } + fwhm = Math.pow(fwhm, 0.5); + } + // 通过energy带入到FHWM公式中,将结果energy转化channel,加减1.25之后取这个范围之内的baseline进行加和 + List energyList = Lists.newLinkedList(); + energyList.add(energy - (fwhm - 1.25)); + // 使用gamma公式将能量转换为道址 + CalValuesOut energyToChannel = CalValuesHandler.energyToChannel(energyList, userEnerParaP); + + long begin = Math.round(energyToChannel.counts.get(0)); + Console.log("nuclide:{},energy:{},fwhmL:{},beginChannel:{}",nuclideName, energy, (fwhm - 1.25), begin); + energyList = Lists.newLinkedList(); + energyList.add(energy + (fwhm + 1.25)); + energyToChannel = CalValuesHandler.energyToChannel(energyList, userEnerParaP); + long end = Math.round(energyToChannel.counts.get(0)); + Console.log("nuclide:{},energy:{},fwhmR:{},endChannel:{}",nuclideName, energy, (fwhm + 1.25), end); + if (begin >= 0 && end <= vBase.size()) { + for (long i = begin; i < end; i++) { + baseLineCount += vBase.get((int)i); + } + } + return baseLineCount; + } + +} diff --git a/jeecg-module-beta-gamma-analyser/src/main/java/org/jeecg/modules/entity/vo/SelfXeResults.java b/jeecg-module-beta-gamma-analyser/src/main/java/org/jeecg/modules/entity/vo/SelfXeResults.java new file mode 100644 index 00000000..18fd3080 --- /dev/null +++ b/jeecg-module-beta-gamma-analyser/src/main/java/org/jeecg/modules/entity/vo/SelfXeResults.java @@ -0,0 +1,36 @@ +package org.jeecg.modules.entity.vo; + +import lombok.Data; + +@Data +public class SelfXeResults { + /** + * 核素名称 + */ + private String nuclideName; + /** + * 感兴趣区活度浓度 + */ + private Double conc; + + /** + * 感兴趣区活度浓度不确定度 + */ + private Double concErr; + /** + * 感兴趣区MDC + */ + private Double mdc; + /** + * 感兴趣区MDC + */ + private Double mda; + /** + * 感兴趣区LC + */ + private Double lc; + /** + * 感兴趣区识别标示;1:识别到,0,未识别到 + */ + private Integer nidFlag; +} diff --git a/jeecg-module-beta-gamma-analyser/src/main/java/org/jeecg/modules/native_jni/struct/SelfBgAnalyseResult.java b/jeecg-module-beta-gamma-analyser/src/main/java/org/jeecg/modules/native_jni/struct/SelfBgAnalyseResult.java new file mode 100644 index 00000000..22fa8aba --- /dev/null +++ b/jeecg-module-beta-gamma-analyser/src/main/java/org/jeecg/modules/native_jni/struct/SelfBgAnalyseResult.java @@ -0,0 +1,26 @@ +package org.jeecg.modules.native_jni.struct; + +import lombok.Data; +import org.jeecg.modules.entity.vo.SelfXeResults; + +import java.util.List; + +@Data +public class SelfBgAnalyseResult { + + List xeResults; + + List s_b_fitting_e_c; + List s_g_fitting_e_c; + + /** + * 分析结果标记,true成功,false失败 + */ + boolean analyse_flag; + /** + * 失败原因 + */ + String error_log; + + +}