diff --git a/app.db b/app.db index dba089e..053c77b 100644 Binary files a/app.db and b/app.db differ diff --git a/pom.xml b/pom.xml index d145171..30597bd 100644 --- a/pom.xml +++ b/pom.xml @@ -29,6 +29,11 @@ compile + net.sourceforge.javacsv + javacsv + 2.0 + + org.projectlombok lombok annotationProcessor diff --git a/src/main/java/a8k/SpringBootBeanUtil.java b/src/main/java/a8k/SpringBootBeanUtil.java index 27369e9..cafa669 100644 --- a/src/main/java/a8k/SpringBootBeanUtil.java +++ b/src/main/java/a8k/SpringBootBeanUtil.java @@ -18,6 +18,7 @@ public class SpringBootBeanUtil implements ApplicationContextAware { if (SpringBootBeanUtil.applicationContext == null) { SpringBootBeanUtil.applicationContext = applicationContext; } + } /** diff --git a/src/main/java/a8k/service/app/appctrl/ConsumablesScanService.java b/src/main/java/a8k/service/app/appctrl/ConsumablesScanService.java index 02f4070..371551f 100644 --- a/src/main/java/a8k/service/app/appctrl/ConsumablesScanService.java +++ b/src/main/java/a8k/service/app/appctrl/ConsumablesScanService.java @@ -87,13 +87,13 @@ public class ConsumablesScanService { return ret; } - if (reactionType.equals(A8kReactionFlowType.ReactionWithLittBS)) { + if (reactionType.equals(A8kReactionFlowType.FlowType1)) { //校验小瓶缓冲液,小瓶缓冲液+样本 if (rawResult.littBSScanResult == null) { ret.state = ScanResultState.LostLittSB; return ret; } - } else if (reactionType.equals(A8kReactionFlowType.ReactionWithLarBsAndDetection)) { + } else if (reactionType.equals(A8kReactionFlowType.FlowType2)) { // 校验大瓶缓冲液,大瓶缓冲液+小瓶缓冲液+样本 if (rawResult.larBSScanResult == null) { ret.state = ScanResultState.LostLarBS; @@ -121,10 +121,10 @@ public class ConsumablesScanService { assert reactionType != null; cState.reactionPlateGroup[ch] = new ReactionPlateGroup(result.projIndex, a8kIdCardInfo.projName, result.lotId, a8kIdCardInfo.color, AppConstant.CONSUMABLE_NUM); - if (reactionType.equals(A8kReactionFlowType.ReactionWithLittBS)) { + if (reactionType.equals(A8kReactionFlowType.FlowType1)) { cState.littBSGroup[ch] = new LittBSGroup(result.projIndex, a8kIdCardInfo.projName, result.lotId, a8kIdCardInfo.color, AppConstant.CONSUMABLE_NUM); cState.larBSGroup[ch] = new LarBSGroup(); - } else if (reactionType.equals(A8kReactionFlowType.ReactionWithLarBsAndDetection)) { + } else if (reactionType.equals(A8kReactionFlowType.FlowType2)) { cState.littBSGroup[ch] = new LittBSGroup(result.projIndex, a8kIdCardInfo.projName, result.lotId, a8kIdCardInfo.color, AppConstant.CONSUMABLE_NUM); cState.larBSGroup[ch] = new LarBSGroup(result.projIndex, a8kIdCardInfo.projName, result.lotId, a8kIdCardInfo.color, AppConstant.CONSUMABLE_NUM); } else { diff --git a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java index 0776dec..f1237f9 100644 --- a/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java +++ b/src/main/java/a8k/service/app/appctrl/mainflowctrl/action/SEQ3_APPLAY_RESOURCE.java @@ -1,6 +1,7 @@ package a8k.service.app.appctrl.mainflowctrl.action; import a8k.service.db.type.A8kProjectInfo; +import a8k.utils.A8kProjCfg; import a8k.utils.AppExceptionBuilder; import a8k.hardware.type.a8kcanprotocol.A8kEcode; import a8k.service.app.appctrl.mainflowctrl.CondtionMgrService; @@ -99,11 +100,11 @@ public class SEQ3_APPLAY_RESOURCE extends A8kStepAction { assert consumables != null; assert incubatorPoss != null; //找到项目对应的A8kIdCardInfo - List a8kIdCardInfo = new ArrayList<>(); + List projCfgs = new ArrayList<>(); for (Consumable consumable : consumables) { - A8kIdCardInfo idcardInfo = appProjInfoMgrService.getA8kIdCardInfoByLotId(consumable.lotId); - assert idcardInfo != null; - a8kIdCardInfo.add(idcardInfo); + var projCfg = appProjInfoMgrService.getProjCfgByProjIndex(consumable.lotId); + assert projCfg != null; + projCfgs.add(projCfg); } List projInfos = new ArrayList<>(); @@ -120,7 +121,7 @@ public class SEQ3_APPLAY_RESOURCE extends A8kStepAction { tipPos.add(tips); } //创建项目处理上下文 - tubeStateMgrService.setTubeResourceIsReady(a8kIdCardInfo, consumables, tipPos, incubatorPoss); + tubeStateMgrService.setTubeResourceIsReady(projCfgs, consumables, tipPos, incubatorPoss); logger.info("apply resource ok"); } diff --git a/src/main/java/a8k/service/app/appdata/AppProjInfoMgrService.java b/src/main/java/a8k/service/app/appdata/AppProjInfoMgrService.java index f28a4ed..effd3ac 100644 --- a/src/main/java/a8k/service/app/appdata/AppProjInfoMgrService.java +++ b/src/main/java/a8k/service/app/appdata/AppProjInfoMgrService.java @@ -8,6 +8,8 @@ import a8k.extapi_controler.utils.ExtApiFn; import a8k.extapi_controler.utils.ExtApiTab; import a8k.hardware.type.regindex.RegIndex; import a8k.service.db.A8kProjInfoDBService; +import a8k.service.db.A8kProjOptConfigDBService; +import a8k.service.db.type.A8kProjOptConfig; import a8k.service.db.type.A8kProjectInfo; import a8k.type.exception.AppException; import a8k.service.bases.AppEventBusService; @@ -16,6 +18,7 @@ import a8k.hardware.type.a8kcanprotocol.*; import a8k.service.db.type.a8kidcard.zenum.A8kReactionFlowType; import a8k.service.db.type.A8kIdCardInfo; import a8k.utils.A8kIdCardDataParser; +import a8k.utils.A8kProjCfg; import a8k.utils.wq.ZWorkQueue; import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; @@ -36,16 +39,16 @@ public class AppProjInfoMgrService { } @Resource - A8kCanBusService canBus; - + A8kCanBusService canBus; @Resource AppEventBusService eventBus; @Resource - A8kProjIdCardDBService a8kProjIdCardDBService; - + A8kProjIdCardDBService a8kProjIdCardDBService; + @Resource + A8kProjInfoDBService a8kProjInfoDBService; @Resource - A8kProjInfoDBService a8kProjInfoDBService; + A8kProjOptConfigDBService a8kProjOptConfigDBService; // //预设项目信息 A8kIdCardInfo mountedIdCardInfo; @@ -136,6 +139,14 @@ public class AppProjInfoMgrService { return a8kProjInfoDBService.findByProjIndex(projIndex); } + public A8kProjCfg getProjCfgByProjIndex(String lotid) { + A8kProjCfg projCfg = new A8kProjCfg(); + projCfg.idCardInfo = getA8kIdCardInfoByLotId(lotid); + projCfg.projectInfo = getProjInfoByProjIndex(projCfg.idCardInfo.projIndex); + projCfg.projOptConfigList = a8kProjOptConfigDBService.findByProjIndex(projCfg.idCardInfo.projIndex); + return projCfg; + } + public String getProjNameByLotId(Integer projIndex) { var idCard = a8kProjIdCardDBService.getProjInfoByProjIndex(projIndex); if (idCard == null) { diff --git a/src/main/java/a8k/service/app/appdata/AppReactionResultMgrService.java b/src/main/java/a8k/service/app/appdata/AppReactionResultMgrService.java index 0f64659..f7eb6a9 100644 --- a/src/main/java/a8k/service/app/appdata/AppReactionResultMgrService.java +++ b/src/main/java/a8k/service/app/appdata/AppReactionResultMgrService.java @@ -57,9 +57,9 @@ public class AppReactionResultMgrService { record.sampleUserid = tubeContext.userid; record.sampleId = tubeContext.sampleid; record.projName = projContext.projName; - record.lotId = projContext.a8kIdCardInfo.lotId; - record.projIndex = projContext.a8kIdCardInfo.projIndex; - record.expiryDate = projContext.a8kIdCardInfo.expiryDate; + record.lotId = projContext.projCfg.idCardInfo.lotId; + record.projIndex = projContext.projCfg.idCardInfo.projIndex; + record.expiryDate = projContext.projCfg.idCardInfo.expiryDate; record.operator = operator; record.appVersion = gstate.getAppVersion(); record.mcuVersion = gstate.getMcuVersion(); diff --git a/src/main/java/a8k/service/app/appstate/TubeStateMgrService.java b/src/main/java/a8k/service/app/appstate/TubeStateMgrService.java index b8da9ae..4a2c69c 100644 --- a/src/main/java/a8k/service/app/appstate/TubeStateMgrService.java +++ b/src/main/java/a8k/service/app/appstate/TubeStateMgrService.java @@ -9,6 +9,7 @@ import a8k.type.Consumable; import a8k.type.IncubatorPos; import a8k.type.TipPos; import a8k.service.db.type.A8kIdCardInfo; +import a8k.utils.A8kProjCfg; import jakarta.annotation.Resource; import org.jetbrains.annotations.NotNull; import org.springframework.stereotype.Component; @@ -125,12 +126,13 @@ public class TubeStateMgrService { } - synchronized public void createProjProcessContext(@NotNull Tube tube, @NotNull A8kIdCardInfo idCardInfo, @NotNull Consumable consumable, @NotNull List tipPos, + synchronized public void createProjProcessContext(@NotNull Tube tube, @NotNull A8kProjCfg projCfg, @NotNull Consumable consumable, @NotNull List tipPos, @NotNull IncubatorPos incubatorPos) { ProjProcessContext context = new ProjProcessContext(); - context.projIndex = idCardInfo.projIndex; - context.projName = idCardInfo.projName; - context.a8kIdCardInfo = idCardInfo; + context.projIndex = projCfg.projectInfo.projIndex; + context.projName = projCfg.projectInfo.projName; + context.projShortName = projCfg.projectInfo.projShortName; + context.projCfg = projCfg; context.consumable = consumable; context.incubatorPos = incubatorPos; context.tipPos = tipPos; @@ -148,12 +150,12 @@ public class TubeStateMgrService { tube.state = state; } - synchronized public void setTubeResourceIsReady(@NotNull List idCardInfo, @NotNull List consumable, @NotNull List> tipPos, + synchronized public void setTubeResourceIsReady(@NotNull List a8kconfig, @NotNull List consumable, @NotNull List> tipPos, @NotNull List incubatorPos) { Tube tube = gstate.getCurProcessingTube(); assert tube != null; for (int i = 0; i < tube.projIndex.size(); i++) { - createProjProcessContext(tube, idCardInfo.get(i), consumable.get(i), tipPos.get(i), incubatorPos.get(i)); + createProjProcessContext(tube, a8kconfig.get(i), consumable.get(i), tipPos.get(i), incubatorPos.get(i)); } tube.state = TubeState.RESOURCE_IS_READY; } diff --git a/src/main/java/a8k/service/app/appstate/type/ProjProcessContext.java b/src/main/java/a8k/service/app/appstate/type/ProjProcessContext.java index 0ba2097..66e4b38 100644 --- a/src/main/java/a8k/service/app/appstate/type/ProjProcessContext.java +++ b/src/main/java/a8k/service/app/appstate/type/ProjProcessContext.java @@ -4,6 +4,7 @@ import a8k.type.Consumable; import a8k.type.IncubatorPos; import a8k.type.TipPos; import a8k.service.db.type.A8kIdCardInfo; +import a8k.utils.A8kProjCfg; import java.util.List; @@ -11,11 +12,12 @@ public class ProjProcessContext { public String uuid; public String sampleId; //样本ID-系统生成-唯一标识一个样本 - public Integer projIndex;//项目代码 - public String projName; - public A8kIdCardInfo a8kIdCardInfo;//a8k卡信息 - public Consumable consumable;//耗材绑定的通道号 - public IncubatorPos incubatorPos;//孵育位置 - public List tipPos;//吸头位置 + public Integer projIndex;//项目代码 + public String projName; + public String projShortName; + public A8kProjCfg projCfg;//项目配置 + public Consumable consumable;//耗材绑定的通道号 + public IncubatorPos incubatorPos;//孵育位置 + public List tipPos;//吸头位置 } diff --git a/src/main/java/a8k/service/db/A8kProjInfoDBService.java b/src/main/java/a8k/service/db/A8kProjInfoDBService.java index ec4f6d9..13d55d5 100644 --- a/src/main/java/a8k/service/db/A8kProjInfoDBService.java +++ b/src/main/java/a8k/service/db/A8kProjInfoDBService.java @@ -3,6 +3,7 @@ package a8k.service.db; import a8k.service.app.appdata.UtilsProjectColorAllocer; import a8k.service.db.type.A8kProjectInfo; import a8k.utils.ZSqliteJdbcHelper; +import com.csvreader.CsvReader; import jakarta.annotation.PostConstruct; import jakarta.annotation.Resource; import lombok.SneakyThrows; @@ -11,6 +12,8 @@ import org.slf4j.LoggerFactory; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; +import java.io.FileNotFoundException; +import java.io.IOException; import java.sql.ResultSet; import java.util.List; @@ -32,6 +35,16 @@ public class A8kProjInfoDBService { if (!ZSqliteJdbcHelper.isTableExist(jdbcTemplate, tableName)) { ZSqliteJdbcHelper.createTable(jdbcTemplate, tableName, tClass); } + + try { + CsvReader csvReader = new CsvReader("src/main/resources/zapp_a8k_proj_info.csv", ','); + csvReader.readHeaders(); + while (csvReader.readRecord()){ + logger.info(csvReader.get("xxxxx")); + } + } catch (IOException e) { + throw new RuntimeException(e); + } } @SneakyThrows private A8kProjectInfo rowMapper(ResultSet rs, int rowNum) { diff --git a/src/main/java/a8k/service/db/A8kProjOptConfigDBService.java b/src/main/java/a8k/service/db/A8kProjOptConfigDBService.java new file mode 100644 index 0000000..0de5af7 --- /dev/null +++ b/src/main/java/a8k/service/db/A8kProjOptConfigDBService.java @@ -0,0 +1,52 @@ +package a8k.service.db; + +import a8k.service.app.appdata.UtilsProjectColorAllocer; +import a8k.service.db.type.A8kProjOptConfig; +import a8k.utils.ZSqliteJdbcHelper; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import lombok.SneakyThrows; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Component; + +import java.sql.ResultSet; +import java.util.List; + +@Component +public class A8kProjOptConfigDBService { + private static final Logger logger = LoggerFactory.getLogger(A8kProjOptConfigDBService.class); + private static final String tableName = "zapp_a8k_project_opt_config"; + private static final Class tClass = A8kProjOptConfig.class; + + + @Resource + JdbcTemplate jdbcTemplate; + + @Resource + UtilsProjectColorAllocer colorAllocer; + + @PostConstruct + void init() { + if (!ZSqliteJdbcHelper.isTableExist(jdbcTemplate, tableName)) { + ZSqliteJdbcHelper.createTable(jdbcTemplate, tableName, tClass); + } + } + + @SneakyThrows private A8kProjOptConfig rowMapper(ResultSet rs, int rowNum) { + return (A8kProjOptConfig) ZSqliteJdbcHelper.rowMapper(rs, tClass); + } + + public List findByProjIndex(Integer projIndex) { + List list = jdbcTemplate.query("select * from " + tableName + " where projIndex = ?;", this::rowMapper, projIndex); + if (list.isEmpty()) { + return null; + } + return list; + } + + public void add(A8kProjOptConfig val) { + ZSqliteJdbcHelper.addObj(jdbcTemplate, tableName, tClass, val); + } +} diff --git a/src/main/java/a8k/service/db/type/A8kProjOptConfig.java b/src/main/java/a8k/service/db/type/A8kProjOptConfig.java new file mode 100644 index 0000000..d986879 --- /dev/null +++ b/src/main/java/a8k/service/db/type/A8kProjOptConfig.java @@ -0,0 +1,25 @@ +package a8k.service.db.type; + +import a8k.service.db.type.a8kidcard.zenum.A8kOptType; +import a8k.service.db.type.a8kprojinfo.OptScanDirection; +import a8k.service.db.type.a8kprojinfo.PeakName; + +import java.util.List; + +public class A8kProjOptConfig { + public int id; + public Integer projIndex; //项目INDEX + public String projName; //项目名称 + public Integer subProjIndex;//子项目INDEX + /*光学配置*/ + public String subProjName; //子项目 名称 + public String subProjShortName; //子项目 缩写名称 + public A8kOptType subProjOptType; //子项目 光学类型 + public Integer subProjScanRange; //子项目 扫描范围 + public OptScanDirection subProjScanDirection; //子项目 扫描方向 + public Integer subProjPeakNum; //子项目 峰的数量 + public List subProjPeakNames; //子项目 峰的名称 + public List subProjPeakPos; //子项目 峰的位置 + public Integer subProjOptLaserAmplFactor; //子项目 发射放大系数 + public Integer subProjOptScanFactor; //子项目 扫描放大系数 +} diff --git a/src/main/java/a8k/service/db/type/A8kProjectInfo.java b/src/main/java/a8k/service/db/type/A8kProjectInfo.java index 0919133..a9e39d9 100644 --- a/src/main/java/a8k/service/db/type/A8kProjectInfo.java +++ b/src/main/java/a8k/service/db/type/A8kProjectInfo.java @@ -1,66 +1,33 @@ package a8k.service.db.type; -import a8k.optalgo.type.Peak; -import a8k.service.db.type.a8kidcard.zenum.A8kOptType; import a8k.service.db.type.a8kidcard.zenum.A8kReactionFlowType; -import a8k.service.db.type.a8kprojinfo.OptScanDirection; -import a8k.service.db.type.a8kprojinfo.PeakName; - -import java.util.List; public class A8kProjectInfo { - public int id; - public String color; //项目颜色 + public int id; + + /*基础配置*/ public Integer projIndex; //项目index public String projName; //项目名称 - + public String projShortName;//项目缩写词 public Integer projNum; //是否是多联卡 public Integer reactionTemperature; //反应温度 + public String color; //项目颜色 - //流程类型 + /*流程类型*/ public A8kReactionFlowType reactionFlowType; //反应流程 - //样本配置 - public Integer wBloodSampleVolUl; // 全血样本量 0x0037 - public Integer serumSampleVolUl; // 血清/血浆样本量 0x0038 - public Integer shakeTimes; // 摇匀次数 - - //缓冲液配置 - public Integer bigBufferSampleUl; // 大瓶缓冲液取样量 - - //样本处理逻辑 - public Integer tubeMixingCount; //试管混匀次数 0x0039 - - //混合液配置 - public Integer mixLiquidReactionTime; // 混合液反应时间 - public Integer mixLiquidAspirMixingCnt; // 混合混匀次数 - - //孵育配置 - public Integer reactionPlateIncubationTime; // 反应板孵育时间 - public Integer reactionPlateDropletVol; // 反应板滴样量 + /*样本配置*/ + public Integer wBloodSampleVolUl; //全血样本量ul + public Integer serumSampleVolUl; //血清/血浆样本量ul + public Integer shakeTimes; //摇匀次数 - //光学配置 - public String subProj0_name; //子项目名称 - public A8kOptType subProj0_optType; //F,T - public Integer subProj0_scanRange; //扫描范围 - public OptScanDirection subProj0_scanDirection; //扫描方向 - public Integer subProj0_peakNum; //峰的数量 - public List subProj0_peakNames; //峰的名称 - public List subProj0_peakPos; //峰的位置 + /*缓冲液配置*/ + public Integer bigBufferSampleUl; //大瓶缓冲液取样量ul - public String subProj1_name; //子项目名称 - public A8kOptType subProj1_optType; //F,T - public Integer subProj1_scanRange; //扫描范围 - public OptScanDirection subProj1_scanDirection; //扫描方向 - public Integer subProj1_peakNum; //峰的数量 - public List subProj1_peakNames; //峰的名称 - public List subProj1_peakPos; //峰的位置 + /*混合液配置*/ + public Integer mixLiquidAspirMixingCnt; //混合混匀次数 - public String subProj2_name; //子项目名称 - public A8kOptType subProj2_optType; //F,T - public Integer subProj2_scanRange; //扫描范围 - public OptScanDirection subProj2_scanDirection; //扫描方向 - public Integer subProj2_peakNum; //峰的数量 - public List subProj2_peakNames; //峰的名称 - public List subProj2_peakPos; //峰的位置 + /*孵育配置*/ + public Integer reactionPlateIncubationTime; //反应板孵育时间Min + public Integer reactionPlateDropletVolUl; //反应板滴样量ul } diff --git a/src/main/java/a8k/service/db/type/a8kidcard/zenum/A8kOptType.java b/src/main/java/a8k/service/db/type/a8kidcard/zenum/A8kOptType.java index 6879ea3..ede830d 100644 --- a/src/main/java/a8k/service/db/type/a8kidcard/zenum/A8kOptType.java +++ b/src/main/java/a8k/service/db/type/a8kidcard/zenum/A8kOptType.java @@ -1,6 +1,6 @@ package a8k.service.db.type.a8kidcard.zenum; public enum A8kOptType { - Fopt, - Topt, + F, + T, } diff --git a/src/main/java/a8k/service/db/type/a8kidcard/zenum/A8kReactionFlowType.java b/src/main/java/a8k/service/db/type/a8kidcard/zenum/A8kReactionFlowType.java index 894d1f5..bffbf5f 100644 --- a/src/main/java/a8k/service/db/type/a8kidcard/zenum/A8kReactionFlowType.java +++ b/src/main/java/a8k/service/db/type/a8kidcard/zenum/A8kReactionFlowType.java @@ -12,7 +12,7 @@ public enum A8kReactionFlowType { * 取样 * 滴定 */ - ReactionWithLittBS(1, 2), //样本和小瓶缓冲反应 + FlowType1(1, 2), //样本和小瓶缓冲反应 /** * @@ -28,7 +28,7 @@ public enum A8kReactionFlowType { * 取样 * 滴定 */ - ReactionWithLarBsAndDetection(2, 2),//样本,大瓶缓冲液,探测物质反应 + FlowType2(2, 2),//样本,大瓶缓冲液,探测物质反应 ; public final int tipUseNum; public final int valInIdCard; diff --git a/src/main/java/a8k/utils/A8kProjCfg.java b/src/main/java/a8k/utils/A8kProjCfg.java new file mode 100644 index 0000000..3b02f1d --- /dev/null +++ b/src/main/java/a8k/utils/A8kProjCfg.java @@ -0,0 +1,13 @@ +package a8k.utils; + +import a8k.service.db.type.A8kIdCardInfo; +import a8k.service.db.type.A8kProjOptConfig; +import a8k.service.db.type.A8kProjectInfo; + +import java.util.List; + +public class A8kProjCfg { + public A8kProjectInfo projectInfo; + public A8kIdCardInfo idCardInfo; + public List projOptConfigList; +} diff --git a/src/main/resources/zapp_a8k_proj_info.csv b/src/main/resources/zapp_a8k_proj_info.csv new file mode 100644 index 0000000..719595c --- /dev/null +++ b/src/main/resources/zapp_a8k_proj_info.csv @@ -0,0 +1,2 @@ +projIndex,projName,projShortName,projNum,reactionTemperature,color,reactionFlowType,wBloodSampleVolUl,serumSampleVolUl,shakeTimes,bigBufferSampleUl,mixLiquidAspirMixingCnt,reactionPlateIncubationTime,reactionPlateDropletVolUl,subProj1_name,subProj1_shortName,subProj1_optType,subProj1_scanRange,subProj1_scanDirection,subProj1_peakNum,subProj1_peakNames,subProj1_peakPos,subProj1_optLaserAmplFactor,subProj1_optScanFactor,subProj2_name,subProj2_shortName,subProj2_optType,subProj2_scanRange,subProj2_scanDirection,subProj2_peakNum,subProj2_peakNames,subProj2_peakPos,subProj2_optLaserAmplFactor,subProj2_optScanFactor,subProj3_name,subProj3_shortName,subProj3_optType,subProj3_scanRange,subProj3_scanDirection,subProj3_peakNum,subProj3_peakNames,subProj3_peakPos,subProj3_optLaserAmplFactor,subProj3_optScanFactor +Ŀindex,Ŀ,Ŀд,ǷǶ,Ӧ¶,Ŀɫ,Ӧ,ȫѪul,Ѫ/Ѫul,ҡȴ,ƿҺȡul,ϻȴ,ӦʱMin,Ӧul,Ŀ1_,Ŀ1_д,Ŀ1_ѧ,Ŀ1_ɨ跶Χ,Ŀ1_ɨ跽,Ŀ1_,Ŀ1_,Ŀ1_λ,Ŀ1_Ŵϵ,Ŀ1_ɨŴϵ,Ŀ2_,Ŀ1_д,Ŀ2_ѧ,Ŀ2_ɨ跶Χ,Ŀ2_ɨ跽,Ŀ2_,Ŀ2_,Ŀ2_λ,Ŀ2_Ŵϵ,Ŀ2_ɨŴϵ,Ŀ3_,Ŀ1_д,Ŀ3_ѧ,Ŀ3_ɨ跶Χ,Ŀ3_ɨ跽,Ŀ3_,Ŀ3_,Ŀ3_λ,Ŀ3_Ŵϵ,Ŀ3_ɨŴϵ \ No newline at end of file