diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..38aa69a --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ +/out diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..108d919 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 ZZHow(ZZHow1024) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 0d7a785..03e04b1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,65 @@ -# MagicSEGY -MagicSEGY.Developing with Java. +# [Java 项目]ZSEGY(中文说明) + +--- + +Website: + +[[Java 项目]ZSEGY | ZZHow](https://www.zzhow.com/ZSEGY) + +Source Code: + +https://github.com/ZZHow1024/ZSEGY + +Releases: + +https://github.com/ZZHow1024/ZSEGY/releases + +--- + +## 它是什么? + +ZSEGY 是一款跨平台的 SEG-Y 文件解析工具,支持命令模式和交互模式,可以解析并显示 SEG-Y 文件的文件头和数据体。 + +--- + +## 许可证 + +该项目根据 MIT 许可证获得许可 - 有关详细信息,请参阅 [LICENSE](https://github.com/ZZHow1024/ZSEGY/blob/main/LICENSE) 文件。 + +--- + +## 使用说明 + +下载地址:https://github.com/ZZHow1024/ZSEGY/releases + +- 下载 .jar 文件 +- 命令模式: + - 通过 `java -jar zsegy.jar [-command] [filePath]` 命令使用软件。 + - -head [filePath]:解析并输出文件头 + - -body [filePath]:解析并输出数据体中的第 num 个数据道 + - -all [filePath]:解析并输出文件头和数据体中的第 num 个数据道 + -i [filePath]:解析并进入交互模式 + - help:呼出本提示 +- 交互模式: + - 通过 `java -jar zsegy.jar` 命令使用软件。 + 1. 指定文件全路径 + 2. 展示文件头 + 3. 展示数据体 + 4. 退出程序 + +--- + +## 各版本功能介绍 + +- ZSEGY1.0.0 + - 解析 SEG-Y文件 + - 输出解析后的内容 + - 支持命令模式与交互模式 + +--- + +## 各版本主界面 + +![ZSEGY1.0.0](https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4b165318-6383-451c-8845-110b786c9f0a%2F77686c07-8ce0-4713-9982-c0fbb624147e%2FZSEGY1.0.0.png?table=block&id=14ae64bd-e40f-8010-b353-e36c9a36e3d9&t=14ae64bd-e40f-8010-b353-e36c9a36e3d9&width=434&cache=v2) + +ZSEGY1.0.0 \ No newline at end of file diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..37197ef --- /dev/null +++ b/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: Main + diff --git a/src/Main.java b/src/Main.java new file mode 100644 index 0000000..31b57af --- /dev/null +++ b/src/Main.java @@ -0,0 +1,131 @@ +import pojo.entity.SEGY; +import util.SEGYUtils; + +import java.io.File; +import java.util.Scanner; + +/** + * @author ZZHow + * @date 2024/11/25 + */ +public class Main { + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + SEGY segy = new SEGY(); + String filePath = ""; + + System.out.println("ZSEGY 1.0.0"); + System.out.println("Author: ZZHow"); + + if (args.length != 0) { + + switch (args[0]) { + case "-head", "head" -> { + System.out.println("正在解析中..."); + System.out.println(SEGYUtils.parseFileHeader(args[1])); + System.exit(0); + } + case "-body", "body" -> { + long num = 1; + try { + num = Long.parseLong(args[1]); + } catch (NumberFormatException e) { + System.out.println("格式错误,输入 -help 查看提示"); + System.exit(0);; + } + segy = SEGYUtils.parseSEGY(args[2]); + System.out.println("\n@@@第 " + num + " 个数据道@@@"); + System.out.println(segy.getDataBodies().get(num)); + System.exit(0); + } + case "-all", "all" -> { + long num; + try { + num = Long.parseLong(args[1]); + } catch (NumberFormatException e) { + System.out.println("输入格式错误,输入 -help 查看提示"); + break; + } + segy = SEGYUtils.parseSEGY(args[2]); + System.out.println(segy.getFileHeader()); + System.out.println("\n@@@第 " + num + " 个数据道@@@"); + System.out.println(segy.getDataBodies().get(num)); + System.exit(0); + } + case "-i", "i" -> { + filePath = args[1]; + } + case "-help", "help" -> { + System.out.println("--- ZSEGY 1.0.0 使用说明 ---"); + System.out.println("java -jar zsegy.jar [-command] [filePath]"); + System.out.println("[-command]: "); + System.out.println("-head [filePath]:解析并输出文件头"); + System.out.println("-body [filePath]:解析并输出数据体中的第 num 个数据道"); + System.out.println("-all [filePath]:解析并输出文件头和数据体中的第 num 个数据道"); + System.out.println("-i [filePath]:解析并进入交互模式"); + System.out.println(); + System.out.println("-help:呼出本提示"); + System.exit(0); + } + } + } + + // 交互模式 + // 程序主界面 + System.out.println("0. 指定文件全路径\t\t"); + System.out.println("1. 展示文件头"); + System.out.println("2. 展示数据体"); + System.out.println("3. 退出程序"); + + String op = "-1"; + if (filePath == null || filePath.isEmpty()) { + System.out.println("尚未指定文件"); + op = "0"; + } else { + try { + segy = SEGYUtils.parseSEGY(filePath); + } catch (UnsupportedOperationException e) { + System.out.println("数据采样格式编码错误,请检查"); + } + } + + while (true) { + switch (op) { + case "0" -> { + System.out.println("请输入文件全路径:"); + filePath = scanner.next(); + if (!new File(filePath).exists()) { + filePath = null; + System.out.println("文件不存在!"); + } else { + try { + segy = SEGYUtils.parseSEGY(filePath); + } catch (UnsupportedOperationException e) { + System.out.println("数据采样格式编码错误,请检查"); + } + } + } + case "1" -> { + System.out.println(segy.getFileHeader()); + } + case "2" -> { + System.out.print("数据道数:"); + long num = scanner.nextLong(); + System.out.println(segy.getDataBodies().get(num)); + } + case "3" -> { + System.out.println("程序退出..."); + System.exit(0); + } + case "-1" -> { + } + default -> { + System.out.println("无效输入"); + } + } + System.out.print("->"); + op = scanner.next(); + scanner.nextLine(); + } + } +} \ No newline at end of file diff --git a/src/pojo/entity/DataBody.java b/src/pojo/entity/DataBody.java new file mode 100644 index 0000000..c3b5a16 --- /dev/null +++ b/src/pojo/entity/DataBody.java @@ -0,0 +1,978 @@ +package pojo.entity; + +import java.util.Arrays; + +/** + * @author ZZHow + * @date 2024/11/25 + */ +public class DataBody { + /* 数据体第一部分——道头 */ + // 1-4:测线中道顺序号 + private Integer traceSequenceNumberWithinLine; + // 5-8:SEG Y文件中道顺序号 + private Integer traceSequenceNumberWithinSEGY; + // 9-12:野外原始记录号 + private Integer originalFieldRecordNumber; + // 13-16:野外原始记录的道号 + private Integer traceNumberWithinTheOriginal; + // 17-20:震源点号 + private Integer energySourcePointNumber; + // 21-24:道集号 + private Integer ensembleNumber; + // 25-28:道集的道数 + private Integer traceNumberWithinTheEnsemble; + // 29-30:道识别码 + private Short traceIdentificationCode; + // 31-32:产生该道的垂直叠加道数 + private Short verticallySummedTraces; + // 33-34:产生该道的水平叠加道数 + private Short horizontallyStackedTraces; + // 35-36:数据用途 + private Short dataUse; + // 37-40:从震源中心点到检波器组中心的距离 + private Integer sourcePointToReceiverGroup; + // 41-44:检波器组高程 + private Integer receiverGroupElevation; + // 45-48:震源地表高程 + private Integer surfaceElevationAtSource; + // 49-52:震源距地表深度(正数) + private Integer sourceDepthBelowSurface; + // 53-56:检波器组基准高程 + private Integer datumElevationAtReceiverGroup; + // 57-60:震源基准高程 + private Integer datumElevationAtSource; + // 61-64:震源水深 + private Integer waterDepthAtSource; + // 65-68:检波器组水深 + private Integer waterDepthAtGroup; + // 69-70:应用于所有在道头41-68字节给定的真实高程和深度的因子 + private Short scalar1; + // 71-72:应用于所有在道头73-88字节和181-188字节给定的真实坐标值的因子 + private Short scalar2; + // 73-76:震源坐标――X + private Integer sourceCoordinateX; + // 77-80:震源坐标――Y + private Integer sourceCoordinateY; + // 81-84:检波器组坐标――X + private Integer groupCoordinateX; + // 85-88:检波器组坐标――Y + private Integer groupCoordinateY; + // 89-90:坐标单位 + private Short coordinateUnits; + // 91-92:风化层速度 + private Short weatheringVelocity; + // 93-94:风化层下速度 + private Short subweatheringVelocity; + // 95-96:震源处井口时间(毫秒) + private Short upholeTimeAtSourceInMilliseconds; + // 97-98:检波器组处井口时间(毫秒) + private Short upholeTimeAtGroupInMilliseconds; + // 99-100:震源的静校正量(毫秒) + private Short sourceStaticCorrectionInMilliseconds; + // 101-102:检波器组的校正量(毫秒) + private Short groupStaticCorrectionInMilliseconds; + // 103-104:应用的总静校正量(毫秒)(如没有应用静校正量为零) + private Short totalStaticAppliedInMilliseconds; + // 105-106:延迟时间A + private Short lagTimeA; + // 107-108:延迟时间B + private Short lagTimeB; + // 109-110:记录延迟时间 + private Short delayRecordingTime; + // 111-112:起始切除时间(毫秒) + private Short muteTimeStart; + // 113-114:终止切除时间(毫秒) + private Short muteTimeEnd; + // 115-116:该道采样点数 + private Short numberOfSamplesInThisTrace; + // 117-118:该道采样间隔(微秒) + private Short sampleIntervalInMicroseconds; + // 119-120:野外仪器增益类型 + private Short gainTypeOfFieldInstruments; + // 121-122:仪器增益常数(分贝) + private Short instrumentGainConstant; + // 123-124:仪器初始增益(分贝) + private Short instrumentEarlyOrInitialGain; + // 125-126:相关 + private Short correlated; + // 127-128:起始扫描频率(赫兹) + private Short sweepFrequencyAtStart; + // 129-130:终止扫描频率(赫兹) + private Short sweepFrequencyAtEnd; + // 131-132:扫描长度(毫秒) + private Short sweepLengthInMilliseconds; + // 133-134:扫描类型 + private Short sweepType; + // 135-136:扫描道斜坡起始长度(毫秒) + private Short sweepTraceTaperLengthAtStart; + // 137-138:扫描道斜坡终止长度(毫秒) + private Short sweepTraceTaperLengthAtEnd; + // 139-140:斜坡类型 + private Short taperType; + // 141-142:假频滤波频率(赫兹) + private Short aliasFilterFrequency; + // 143-144:假频滤波坡度(分贝/倍频程) + private Short aliasFilterSlope; + // 145-146:陷波频率(赫兹) + private Short notchFilterFrequency; + // 147-148:陷波坡度(分贝/倍频程) + private Short notchFilterSlope; + // 149-150:低截频率(赫兹) + private Short lowCutFrequency; + // 151-152:高截频率(赫兹) + private Short highCutFrequency; + // 153-154:低截坡度(分贝/倍频程) + private Short lowCutSlope; + // 155-156:高截坡度(分贝/倍频程) + private Short highCutSlope; + // 157-158:数据记录的年 + private Short yearDataRecorded; + // 159-160:日(以格林尼治标准时间和通用协调时间为基准的公元日) + private Short dayOfYear; + // 161-162:时(24小时制) + private Short hourOfDay; + // 163-164:分 + private Short minuteOfHour; + // 165-166:秒 + private Short secondOfMinute; + // 167-168:时间基准码 + private Short timeBasisCode; + // 169-170:道加权因子 + private Short traceWeightingFactor; + // 171-172:滚动开关位置1的检波器组号 + private Short RollSwitchPositionOne; + // 173-174:野外原始记录中道号1的检波器组号 + private Short traceNumberOneWithinOriginal; + // 175-176:野外原始记录中最后一道的检波器组号 + private Short lastTraceWithinOriginal; + // 177-178:间隔大小(滚动时甩掉的总检波器组数) + private Short gapSize; + // 179-180:相对测线斜坡起始或终止点的移动 + private Short overTravelAssociated; + // 181-184:该道的道集(CDP)位置X坐标(应用道头71-72字节的因子) + private Integer xCoordinateOfEnsemble; + // 185-188:该道的道集(CDP)位置Y坐标(应用道头71-72字节的因子) + private Integer yCoordinateOfEnsemble; + // 189-192:对于3-D叠后数据,本字段用来填纵向线号(In-line) + private Integer inLineNumber; + // 193-196:对于3-D叠后数据,本字段用来填横向线号(Cross-line) + private Integer crossLineNumber; + // 197-200:炮点编号 — 这可能仅适用于 2-D 叠后数据 + private Integer shotpointNumber; + // 201-202:应用于道头中197-200字节中炮点号的因子,以得到实际数值 + private Short scalar3; + // 203-204:道值测量单位 + private Short traceValueMeasurementUnit; + // 205-210:转换常数 + private Long transductionConstant; + // 211-212:转换单位 + private Short transductionUnits; + // 213-214:设备/道标识 + private Short deviceTraceIdentifier; + // 215-216:在道头95-114字节给出的作用于时间的因子,以得到真实的毫秒表示的时间值 + private Short scalar4; + // 217-218:震源类型/方位――定义类型或能量源的方位 + private Short sourceTypeOrientation; + // 219-224:相对震源方位的震源能量方向――正方位方向在道头217-218字节定义 + private Long sourceEnergyDirection; + // 225-230:震源测量――描述产生道的震源效应 + private Long sourceMeasurement; + // 231-232:震源测量单位――用于震源测量、道头225-230字节的单位 + private Short sourceMeasurementUnit; + // 233-240:未赋值――为任选信息预留 + /**/ + + private float[] samplingData; + + public DataBody() { + } + + public Integer getTraceSequenceNumberWithinLine() { + return traceSequenceNumberWithinLine; + } + + public Integer getTraceSequenceNumberWithinSEGY() { + return traceSequenceNumberWithinSEGY; + } + + public Integer getOriginalFieldRecordNumber() { + return originalFieldRecordNumber; + } + + public Integer getTraceNumberWithinTheOriginal() { + return traceNumberWithinTheOriginal; + } + + public Integer getEnergySourcePointNumber() { + return energySourcePointNumber; + } + + public Integer getEnsembleNumber() { + return ensembleNumber; + } + + public Integer getTraceNumberWithinTheEnsemble() { + return traceNumberWithinTheEnsemble; + } + + public Short getTraceIdentificationCode() { + return traceIdentificationCode; + } + + public Short getVerticallySummedTraces() { + return verticallySummedTraces; + } + + public Short getHorizontallyStackedTraces() { + return horizontallyStackedTraces; + } + + public Short getDataUse() { + return dataUse; + } + + public Integer getSourcePointToReceiverGroup() { + return sourcePointToReceiverGroup; + } + + public Integer getReceiverGroupElevation() { + return receiverGroupElevation; + } + + public Integer getSurfaceElevationAtSource() { + return surfaceElevationAtSource; + } + + public Integer getSourceDepthBelowSurface() { + return sourceDepthBelowSurface; + } + + public Integer getDatumElevationAtReceiverGroup() { + return datumElevationAtReceiverGroup; + } + + public Integer getDatumElevationAtSource() { + return datumElevationAtSource; + } + + public Integer getWaterDepthAtSource() { + return waterDepthAtSource; + } + + public Integer getWaterDepthAtGroup() { + return waterDepthAtGroup; + } + + public Short getScalar1() { + return scalar1; + } + + public Short getScalar2() { + return scalar2; + } + + public Integer getSourceCoordinateX() { + return sourceCoordinateX; + } + + public Integer getSourceCoordinateY() { + return sourceCoordinateY; + } + + public Integer getGroupCoordinateX() { + return groupCoordinateX; + } + + public Integer getGroupCoordinateY() { + return groupCoordinateY; + } + + public Short getCoordinateUnits() { + return coordinateUnits; + } + + public Short getWeatheringVelocity() { + return weatheringVelocity; + } + + public Short getSubweatheringVelocity() { + return subweatheringVelocity; + } + + public Short getUpholeTimeAtSourceInMilliseconds() { + return upholeTimeAtSourceInMilliseconds; + } + + public Short getUpholeTimeAtGroupInMilliseconds() { + return upholeTimeAtGroupInMilliseconds; + } + + public Short getSourceStaticCorrectionInMilliseconds() { + return sourceStaticCorrectionInMilliseconds; + } + + public Short getGroupStaticCorrectionInMilliseconds() { + return groupStaticCorrectionInMilliseconds; + } + + public Short getTotalStaticAppliedInMilliseconds() { + return totalStaticAppliedInMilliseconds; + } + + public Short getLagTimeA() { + return lagTimeA; + } + + public Short getLagTimeB() { + return lagTimeB; + } + + public Short getDelayRecordingTime() { + return delayRecordingTime; + } + + public Short getMuteTimeStart() { + return muteTimeStart; + } + + public Short getMuteTimeEnd() { + return muteTimeEnd; + } + + public Short getNumberOfSamplesInThisTrace() { + return numberOfSamplesInThisTrace; + } + + public Short getSampleIntervalInMicroseconds() { + return sampleIntervalInMicroseconds; + } + + public Short getGainTypeOfFieldInstruments() { + return gainTypeOfFieldInstruments; + } + + public Short getInstrumentGainConstant() { + return instrumentGainConstant; + } + + public Short getInstrumentEarlyOrInitialGain() { + return instrumentEarlyOrInitialGain; + } + + public Short getCorrelated() { + return correlated; + } + + public Short getSweepFrequencyAtStart() { + return sweepFrequencyAtStart; + } + + public Short getSweepFrequencyAtEnd() { + return sweepFrequencyAtEnd; + } + + public Short getSweepLengthInMilliseconds() { + return sweepLengthInMilliseconds; + } + + public Short getSweepType() { + return sweepType; + } + + public Short getSweepTraceTaperLengthAtStart() { + return sweepTraceTaperLengthAtStart; + } + + public Short getSweepTraceTaperLengthAtEnd() { + return sweepTraceTaperLengthAtEnd; + } + + public Short getTaperType() { + return taperType; + } + + public Short getAliasFilterFrequency() { + return aliasFilterFrequency; + } + + public Short getAliasFilterSlope() { + return aliasFilterSlope; + } + + public Short getNotchFilterFrequency() { + return notchFilterFrequency; + } + + public Short getNotchFilterSlope() { + return notchFilterSlope; + } + + public Short getLowCutFrequency() { + return lowCutFrequency; + } + + public Short getHighCutFrequency() { + return highCutFrequency; + } + + public Short getLowCutSlope() { + return lowCutSlope; + } + + public Short getHighCutSlope() { + return highCutSlope; + } + + public Short getYearDataRecorded() { + return yearDataRecorded; + } + + public Short getDayOfYear() { + return dayOfYear; + } + + public Short getHourOfDay() { + return hourOfDay; + } + + public Short getMinuteOfHour() { + return minuteOfHour; + } + + public Short getSecondOfMinute() { + return secondOfMinute; + } + + public Short getTimeBasisCode() { + return timeBasisCode; + } + + public Short getTraceWeightingFactor() { + return traceWeightingFactor; + } + + public Short getRollSwitchPositionOne() { + return RollSwitchPositionOne; + } + + public Short getTraceNumberOneWithinOriginal() { + return traceNumberOneWithinOriginal; + } + + public Short getLastTraceWithinOriginal() { + return lastTraceWithinOriginal; + } + + public Short getGapSize() { + return gapSize; + } + + public Short getOverTravelAssociated() { + return overTravelAssociated; + } + + public Integer getxCoordinateOfEnsemble() { + return xCoordinateOfEnsemble; + } + + public Integer getyCoordinateOfEnsemble() { + return yCoordinateOfEnsemble; + } + + public Integer getInLineNumber() { + return inLineNumber; + } + + public Integer getCrossLineNumber() { + return crossLineNumber; + } + + public Integer getShotpointNumber() { + return shotpointNumber; + } + + public Short getScalar3() { + return scalar3; + } + + public Short getTraceValueMeasurementUnit() { + return traceValueMeasurementUnit; + } + + public Long getTransductionConstant() { + return transductionConstant; + } + + public Short getTransductionUnits() { + return transductionUnits; + } + + public Short getDeviceTraceIdentifier() { + return deviceTraceIdentifier; + } + + public Short getScalar4() { + return scalar4; + } + + public Short getSourceTypeOrientation() { + return sourceTypeOrientation; + } + + public Long getSourceEnergyDirection() { + return sourceEnergyDirection; + } + + public Long getSourceMeasurement() { + return sourceMeasurement; + } + + public Short getSourceMeasurementUnit() { + return sourceMeasurementUnit; + } + + public float[] getSamplingData() { + return samplingData; + } + + public void setTraceSequenceNumberWithinLine(Integer traceSequenceNumberWithinLine) { + this.traceSequenceNumberWithinLine = traceSequenceNumberWithinLine; + } + + public void setTraceSequenceNumberWithinSEGY(Integer traceSequenceNumberWithinSEGY) { + this.traceSequenceNumberWithinSEGY = traceSequenceNumberWithinSEGY; + } + + public void setOriginalFieldRecordNumber(Integer originalFieldRecordNumber) { + this.originalFieldRecordNumber = originalFieldRecordNumber; + } + + public void setTraceNumberWithinTheOriginal(Integer traceNumberWithinTheOriginal) { + this.traceNumberWithinTheOriginal = traceNumberWithinTheOriginal; + } + + public void setEnergySourcePointNumber(Integer energySourcePointNumber) { + this.energySourcePointNumber = energySourcePointNumber; + } + + public void setEnsembleNumber(Integer ensembleNumber) { + this.ensembleNumber = ensembleNumber; + } + + public void setTraceNumberWithinTheEnsemble(Integer traceNumberWithinTheEnsemble) { + this.traceNumberWithinTheEnsemble = traceNumberWithinTheEnsemble; + } + + public void setTraceIdentificationCode(Short traceIdentificationCode) { + this.traceIdentificationCode = traceIdentificationCode; + } + + public void setVerticallySummedTraces(Short verticallySummedTraces) { + this.verticallySummedTraces = verticallySummedTraces; + } + + public void setHorizontallyStackedTraces(Short horizontallyStackedTraces) { + this.horizontallyStackedTraces = horizontallyStackedTraces; + } + + public void setDataUse(Short dataUse) { + this.dataUse = dataUse; + } + + public void setSourcePointToReceiverGroup(Integer sourcePointToReceiverGroup) { + this.sourcePointToReceiverGroup = sourcePointToReceiverGroup; + } + + public void setReceiverGroupElevation(Integer receiverGroupElevation) { + this.receiverGroupElevation = receiverGroupElevation; + } + + public void setSurfaceElevationAtSource(Integer surfaceElevationAtSource) { + this.surfaceElevationAtSource = surfaceElevationAtSource; + } + + public void setSourceDepthBelowSurface(Integer sourceDepthBelowSurface) { + this.sourceDepthBelowSurface = sourceDepthBelowSurface; + } + + public void setDatumElevationAtReceiverGroup(Integer datumElevationAtReceiverGroup) { + this.datumElevationAtReceiverGroup = datumElevationAtReceiverGroup; + } + + public void setDatumElevationAtSource(Integer datumElevationAtSource) { + this.datumElevationAtSource = datumElevationAtSource; + } + + public void setWaterDepthAtSource(Integer waterDepthAtSource) { + this.waterDepthAtSource = waterDepthAtSource; + } + + public void setWaterDepthAtGroup(Integer waterDepthAtGroup) { + this.waterDepthAtGroup = waterDepthAtGroup; + } + + public void setScalar1(Short scalar1) { + this.scalar1 = scalar1; + } + + public void setScalar2(Short scalar2) { + this.scalar2 = scalar2; + } + + public void setSourceCoordinateX(Integer sourceCoordinateX) { + this.sourceCoordinateX = sourceCoordinateX; + } + + public void setSourceCoordinateY(Integer sourceCoordinateY) { + this.sourceCoordinateY = sourceCoordinateY; + } + + public void setGroupCoordinateX(Integer groupCoordinateX) { + this.groupCoordinateX = groupCoordinateX; + } + + public void setGroupCoordinateY(Integer groupCoordinateY) { + this.groupCoordinateY = groupCoordinateY; + } + + public void setCoordinateUnits(Short coordinateUnits) { + this.coordinateUnits = coordinateUnits; + } + + public void setWeatheringVelocity(Short weatheringVelocity) { + this.weatheringVelocity = weatheringVelocity; + } + + public void setSubweatheringVelocity(Short subweatheringVelocity) { + this.subweatheringVelocity = subweatheringVelocity; + } + + public void setUpholeTimeAtSourceInMilliseconds(Short upholeTimeAtSourceInMilliseconds) { + this.upholeTimeAtSourceInMilliseconds = upholeTimeAtSourceInMilliseconds; + } + + public void setUpholeTimeAtGroupInMilliseconds(Short upholeTimeAtGroupInMilliseconds) { + this.upholeTimeAtGroupInMilliseconds = upholeTimeAtGroupInMilliseconds; + } + + public void setSourceStaticCorrectionInMilliseconds(Short sourceStaticCorrectionInMilliseconds) { + this.sourceStaticCorrectionInMilliseconds = sourceStaticCorrectionInMilliseconds; + } + + public void setGroupStaticCorrectionInMilliseconds(Short groupStaticCorrectionInMilliseconds) { + this.groupStaticCorrectionInMilliseconds = groupStaticCorrectionInMilliseconds; + } + + public void setTotalStaticAppliedInMilliseconds(Short totalStaticAppliedInMilliseconds) { + this.totalStaticAppliedInMilliseconds = totalStaticAppliedInMilliseconds; + } + + public void setLagTimeA(Short lagTimeA) { + this.lagTimeA = lagTimeA; + } + + public void setLagTimeB(Short lagTimeB) { + this.lagTimeB = lagTimeB; + } + + public void setDelayRecordingTime(Short delayRecordingTime) { + this.delayRecordingTime = delayRecordingTime; + } + + public void setMuteTimeStart(Short muteTimeStart) { + this.muteTimeStart = muteTimeStart; + } + + public void setMuteTimeEnd(Short muteTimeEnd) { + this.muteTimeEnd = muteTimeEnd; + } + + public void setNumberOfSamplesInThisTrace(Short numberOfSamplesInThisTrace) { + this.numberOfSamplesInThisTrace = numberOfSamplesInThisTrace; + } + + public void setSampleIntervalInMicroseconds(Short sampleIntervalInMicroseconds) { + this.sampleIntervalInMicroseconds = sampleIntervalInMicroseconds; + } + + public void setGainTypeOfFieldInstruments(Short gainTypeOfFieldInstruments) { + this.gainTypeOfFieldInstruments = gainTypeOfFieldInstruments; + } + + public void setInstrumentGainConstant(Short instrumentGainConstant) { + this.instrumentGainConstant = instrumentGainConstant; + } + + public void setInstrumentEarlyOrInitialGain(Short instrumentEarlyOrInitialGain) { + this.instrumentEarlyOrInitialGain = instrumentEarlyOrInitialGain; + } + + public void setCorrelated(Short correlated) { + this.correlated = correlated; + } + + public void setSweepFrequencyAtStart(Short sweepFrequencyAtStart) { + this.sweepFrequencyAtStart = sweepFrequencyAtStart; + } + + public void setSweepFrequencyAtEnd(Short sweepFrequencyAtEnd) { + this.sweepFrequencyAtEnd = sweepFrequencyAtEnd; + } + + public void setSweepLengthInMilliseconds(Short sweepLengthInMilliseconds) { + this.sweepLengthInMilliseconds = sweepLengthInMilliseconds; + } + + public void setSweepType(Short sweepType) { + this.sweepType = sweepType; + } + + public void setSweepTraceTaperLengthAtStart(Short sweepTraceTaperLengthAtStart) { + this.sweepTraceTaperLengthAtStart = sweepTraceTaperLengthAtStart; + } + + public void setSweepTraceTaperLengthAtEnd(Short sweepTraceTaperLengthAtEnd) { + this.sweepTraceTaperLengthAtEnd = sweepTraceTaperLengthAtEnd; + } + + public void setTaperType(Short taperType) { + this.taperType = taperType; + } + + public void setAliasFilterFrequency(Short aliasFilterFrequency) { + this.aliasFilterFrequency = aliasFilterFrequency; + } + + public void setAliasFilterSlope(Short aliasFilterSlope) { + this.aliasFilterSlope = aliasFilterSlope; + } + + public void setNotchFilterFrequency(Short notchFilterFrequency) { + this.notchFilterFrequency = notchFilterFrequency; + } + + public void setNotchFilterSlope(Short notchFilterSlope) { + this.notchFilterSlope = notchFilterSlope; + } + + public void setLowCutFrequency(Short lowCutFrequency) { + this.lowCutFrequency = lowCutFrequency; + } + + public void setHighCutFrequency(Short highCutFrequency) { + this.highCutFrequency = highCutFrequency; + } + + public void setLowCutSlope(Short lowCutSlope) { + this.lowCutSlope = lowCutSlope; + } + + public void setHighCutSlope(Short highCutSlope) { + this.highCutSlope = highCutSlope; + } + + public void setYearDataRecorded(Short yearDataRecorded) { + this.yearDataRecorded = yearDataRecorded; + } + + public void setDayOfYear(Short dayOfYear) { + this.dayOfYear = dayOfYear; + } + + public void setHourOfDay(Short hourOfDay) { + this.hourOfDay = hourOfDay; + } + + public void setMinuteOfHour(Short minuteOfHour) { + this.minuteOfHour = minuteOfHour; + } + + public void setSecondOfMinute(Short secondOfMinute) { + this.secondOfMinute = secondOfMinute; + } + + public void setTimeBasisCode(Short timeBasisCode) { + this.timeBasisCode = timeBasisCode; + } + + public void setTraceWeightingFactor(Short traceWeightingFactor) { + this.traceWeightingFactor = traceWeightingFactor; + } + + public void setRollSwitchPositionOne(Short rollSwitchPositionOne) { + RollSwitchPositionOne = rollSwitchPositionOne; + } + + public void setTraceNumberOneWithinOriginal(Short traceNumberOneWithinOriginal) { + this.traceNumberOneWithinOriginal = traceNumberOneWithinOriginal; + } + + public void setLastTraceWithinOriginal(Short lastTraceWithinOriginal) { + this.lastTraceWithinOriginal = lastTraceWithinOriginal; + } + + public void setGapSize(Short gapSize) { + this.gapSize = gapSize; + } + + public void setOverTravelAssociated(Short overTravelAssociated) { + this.overTravelAssociated = overTravelAssociated; + } + + public void setxCoordinateOfEnsemble(Integer xCoordinateOfEnsemble) { + this.xCoordinateOfEnsemble = xCoordinateOfEnsemble; + } + + public void setyCoordinateOfEnsemble(Integer yCoordinateOfEnsemble) { + this.yCoordinateOfEnsemble = yCoordinateOfEnsemble; + } + + public void setInLineNumber(Integer inLineNumber) { + this.inLineNumber = inLineNumber; + } + + public void setCrossLineNumber(Integer crossLineNumber) { + this.crossLineNumber = crossLineNumber; + } + + public void setShotpointNumber(Integer shotpointNumber) { + this.shotpointNumber = shotpointNumber; + } + + public void setScalar3(Short scalar3) { + this.scalar3 = scalar3; + } + + public void setTraceValueMeasurementUnit(Short traceValueMeasurementUnit) { + this.traceValueMeasurementUnit = traceValueMeasurementUnit; + } + + public void setTransductionConstant(Long transductionConstant) { + this.transductionConstant = transductionConstant; + } + + public void setTransductionUnits(Short transductionUnits) { + this.transductionUnits = transductionUnits; + } + + public void setDeviceTraceIdentifier(Short deviceTraceIdentifier) { + this.deviceTraceIdentifier = deviceTraceIdentifier; + } + + public void setScalar4(Short scalar4) { + this.scalar4 = scalar4; + } + + public void setSourceTypeOrientation(Short sourceTypeOrientation) { + this.sourceTypeOrientation = sourceTypeOrientation; + } + + public void setSourceEnergyDirection(Long sourceEnergyDirection) { + this.sourceEnergyDirection = sourceEnergyDirection; + } + + public void setSourceMeasurement(Long sourceMeasurement) { + this.sourceMeasurement = sourceMeasurement; + } + + public void setSourceMeasurementUnit(Short sourceMeasurementUnit) { + this.sourceMeasurementUnit = sourceMeasurementUnit; + } + + public void setSamplingData(float[] samplingData) { + this.samplingData = samplingData; + } + + @Override + public String toString() { + return "\n###数据道第一部分###" + + "\n测线中道顺序号=" + traceSequenceNumberWithinLine + + "\nSEG Y文件中道顺序号=" + traceSequenceNumberWithinSEGY + + "\n野外原始记录号=" + originalFieldRecordNumber + + "\n野外原始记录的道号=" + traceNumberWithinTheOriginal + + "\n震源点号=" + energySourcePointNumber + + "\n道集号=" + ensembleNumber + + "\n道集的道数=" + traceNumberWithinTheEnsemble + + "\n道识别码=" + traceIdentificationCode + + "\n产生该道的垂直叠加道数=" + verticallySummedTraces + + "\n产生该道的水平叠加道数=" + horizontallyStackedTraces + + "\n数据用途=" + dataUse + + "\n从震源中心点到检波器组中心的距离=" + sourcePointToReceiverGroup + + "\n检波器组高程=" + receiverGroupElevation + + "\n震源地表高程=" + surfaceElevationAtSource + + "\n震源距地表深度(正数)=" + sourceDepthBelowSurface + + "\n检波器组基准高程=" + datumElevationAtReceiverGroup + + "\n震源基准高程=" + datumElevationAtSource + + "\n震源水深=" + waterDepthAtSource + + "\n检波器组水深=" + waterDepthAtGroup + + "\n应用于所有在道头41-68字节给定的真实高程和深度的因子=" + scalar1 + + "\n应用于所有在道头73-88字节和181-188字节给定的真实坐标值的因子=" + scalar2 + + "\n震源坐标――X=" + sourceCoordinateX + + "\n震源坐标――Y=" + sourceCoordinateY + + "\n检波器组坐标――X=" + groupCoordinateX + + "\n检波器组坐标――Y=" + groupCoordinateY + + "\n坐标单位=" + coordinateUnits + + "\n风化层速度=" + weatheringVelocity + + "\n风化层下速度=" + subweatheringVelocity + + "\n震源处井口时间(毫秒)=" + upholeTimeAtSourceInMilliseconds + + "\n检波器组处井口时间(毫秒)=" + upholeTimeAtGroupInMilliseconds + + "\n震源的静校正量(毫秒)=" + sourceStaticCorrectionInMilliseconds + + "\n检波器组的校正量(毫秒)=" + groupStaticCorrectionInMilliseconds + + "\n应用的总静校正量(毫秒)(如没有应用静校正量为零)=" + totalStaticAppliedInMilliseconds + + "\n延迟时间A=" + lagTimeA + + "\n延迟时间B=" + lagTimeB + + "\n记录延迟时间=" + delayRecordingTime + + "\n起始切除时间(毫秒)=" + muteTimeStart + + "\n终止切除时间(毫秒)=" + muteTimeEnd + + "\n该道采样点数=" + numberOfSamplesInThisTrace + + "\n该道采样间隔(微秒)=" + sampleIntervalInMicroseconds + + "\n野外仪器增益类型=" + gainTypeOfFieldInstruments + + "\n仪器增益常数(分贝)=" + instrumentGainConstant + + "\n仪器初始增益(分贝)=" + instrumentEarlyOrInitialGain + + "\n相关=" + correlated + + "\n起始扫描频率(赫兹)=" + sweepFrequencyAtStart + + "\n终止扫描频率(赫兹)=" + sweepFrequencyAtEnd + + "\n扫描长度(毫秒)=" + sweepLengthInMilliseconds + + "\n扫描类型=" + sweepType + + "\n扫描道斜坡起始长度(毫秒)=" + sweepTraceTaperLengthAtStart + + "\n扫描道斜坡终止长度(毫秒)=" + sweepTraceTaperLengthAtEnd + + "\n斜坡类型=" + taperType + + "\n假频滤波频率(赫兹)=" + aliasFilterFrequency + + "\n假频滤波坡度(分贝/倍频程)=" + aliasFilterSlope + + "\n陷波频率(赫兹)=" + notchFilterFrequency + + "\n陷波坡度(分贝/倍频程)=" + notchFilterSlope + + "\n低截频率(赫兹)=" + lowCutFrequency + + "\n高截频率(赫兹)=" + highCutFrequency + + "\n低截坡度(分贝/倍频程)=" + lowCutSlope + + "\n高截坡度(分贝/倍频程)=" + highCutSlope + + "\n数据记录的年=" + yearDataRecorded + + "\n日(以格林尼治标准时间和通用协调时间为基准的公元日)=" + dayOfYear + + "\n时(24小时制)=" + hourOfDay + + "\n分=" + minuteOfHour + + "\n秒=" + secondOfMinute + + "\n时间基准码=" + timeBasisCode + + "\n道加权因子=" + traceWeightingFactor + + "\n滚动开关位置1的检波器组号=" + RollSwitchPositionOne + + "\n野外原始记录中道号1的检波器组号=" + traceNumberOneWithinOriginal + + "\n野外原始记录中最后一道的检波器组号=" + lastTraceWithinOriginal + + "\n间隔大小(滚动时甩掉的总检波器组数)=" + gapSize + + "\n相对测线斜坡起始或终止点的移动=" + overTravelAssociated + + "\n该道的道集(CDP)位置X坐标(应用道头71-72字节的因子)=" + xCoordinateOfEnsemble + + "\n该道的道集(CDP)位置Y坐标(应用道头71-72字节的因子)=" + yCoordinateOfEnsemble + + "\n对于3-D叠后数据,本字段用来填纵向线号(In-line)=" + inLineNumber + + "\n对于3-D叠后数据,本字段用来填横向线号(Cross-line)=" + crossLineNumber + + "\n炮点编号 — 这可能仅适用于 2-D 叠后数据=" + shotpointNumber + + "\n应用于道头中197-200字节中炮点号的因子=" + scalar3 + + "\n道值测量单位=" + traceValueMeasurementUnit + + "\n转换常数=" + transductionConstant + + "\n转换单位=" + transductionUnits + + "\n设备/道标识=" + deviceTraceIdentifier + + "\n在道头95-114字节给出的作用于时间的因子=" + scalar4 + + "\n震源类型/方位――定义类型或能量源的方位=" + sourceTypeOrientation + + "\n相对震源方位的震源能量方向=" + sourceEnergyDirection + + "\n震源测量=" + sourceMeasurement + + "\n震源测量单位=" + sourceMeasurementUnit + + "\n\n###数据道第二部分###\n" + Arrays.toString(samplingData); + } +} diff --git a/src/pojo/entity/FileHeader.java b/src/pojo/entity/FileHeader.java new file mode 100644 index 0000000..3fba622 --- /dev/null +++ b/src/pojo/entity/FileHeader.java @@ -0,0 +1,365 @@ +package pojo.entity; + +/** + * @author ZZHow + * @date 2024/11/25 + */ +public class FileHeader { + /* 文件头第一部分 */ + // 3200bytes,参数卡:文件头第一部分,EBCDIC字符集 + private String textualFileHeader; + + /* 文件头第二部分 */ + // 3201-3204:作业标识号 + private Integer jobIdentificationNumber; + // 3205-3208:测线号 + private Integer LineNumber; + // 3209-3212:卷号 + private Integer ReelNumber; + // 3213-3214:每个道集的数据道数。叠前数据强制要求 + private Short dataTraces; + // 3215-3216:每个道集的辅助道数。叠前数据强制要求 + private Short auxiliaryTraces; + // 3217-3218:微秒(us)形式的采样间隔。叠前数据强制要求 + private Short sampleIntervalInMicroseconds; + // 3219-3220:微秒(us)形式的原始野外记录采样间隔 + private Short sampleIntervalInMicrosecondsOriginal; + // 3221-3222:数据道采样点数。叠前数据强制要求 + private Short samplesPerDataTrace; + // 3223-3224:原始野外记录每道采样点数 + private Short samplesPerDataTraceOriginal; + // 3225-3226:数据采样格式编码 + private Short dataSampleFormatCode; + // 3227-3228:道集覆盖次数――每个数据集的期望数据道数(例如CMP覆盖次数) + private Short ensembleFold; + // 3229-3230:道分选码(即集合类型) + private Short traceSortingCode; + // 3231-3232:垂直求和码 + private Short verticalSumCode; + // 3233-3234:起始扫描频率(Hz) + private Short sweepFrequencyAtStart; + // 3235-3236:终止扫描频率(Hz) + private Short sweepFrequencyAtEnd; + // 3237-3238:扫描长度(ms) + private Short sweepLength; + // 3239-3240:扫描类型码 + private Short sweepTypeCode; + // 3241-3242:扫描信道的道数 + private Short traceNumberOfSweepChannel; + // 3243-3244:有斜坡时,以毫秒表示的扫描道起始斜坡长度(斜坡从零时刻开始,对这个长度有效) + private Short sweepTraceTaperLengthStart; + // 3245-3246:以毫秒表示的扫描道终止斜坡长度(斜坡终止始于扫描长度减去斜坡结尾处的长度) + private Short sweepTraceTaperLengthEnd; + // 3247-3248:斜坡类型 + private Short taperType; + // 3249-3250:相关数据道 + private Short correlatedDataTraces; + // 3251-3252:二进制增益恢复 + private Short binaryGainRecovered; + // 3253-3254:振幅恢复方法 + private Short amplitudeRecoveryMethod; + // 3255-3256:测量系统 + private Short measurementSystem; + // 3257-3258:脉冲极化码 + private Short impulseSignalPolarity; + // 3259-3260:可控源极化码 + private Short vibratoryPolarityCode; + // 3261-3500:未赋值 + /**/ + // 3501-3502:SEG Y格式修订版号 + private Short SEGYFormatRevisionNumber; + // 3503-3504:固定长度道标志 + private Short fixedLengthTraceFlag; + // 3505-3506:3200字节扩展原文文件头记录在二进制头后 + private Short extendedTextualFileHeader; + // 3507-3600:未赋值 + /**/ + + public FileHeader() { + } + + public String getTextualFileHeader() { + return textualFileHeader; + } + + public Integer getJobIdentificationNumber() { + return jobIdentificationNumber; + } + + public Integer getLineNumber() { + return LineNumber; + } + + public Integer getReelNumber() { + return ReelNumber; + } + + public Short getDataTraces() { + return dataTraces; + } + + public Short getAuxiliaryTraces() { + return auxiliaryTraces; + } + + public Short getSampleIntervalInMicroseconds() { + return sampleIntervalInMicroseconds; + } + + public Short getSampleIntervalInMicrosecondsOriginal() { + return sampleIntervalInMicrosecondsOriginal; + } + + public Short getSamplesPerDataTrace() { + return samplesPerDataTrace; + } + + public Short getSamplesPerDataTraceOriginal() { + return samplesPerDataTraceOriginal; + } + + public Short getDataSampleFormatCode() { + return dataSampleFormatCode; + } + + public Short getEnsembleFold() { + return ensembleFold; + } + + public Short getTraceSortingCode() { + return traceSortingCode; + } + + public Short getVerticalSumCode() { + return verticalSumCode; + } + + public Short getSweepFrequencyAtStart() { + return sweepFrequencyAtStart; + } + + public Short getSweepFrequencyAtEnd() { + return sweepFrequencyAtEnd; + } + + public Short getSweepLength() { + return sweepLength; + } + + public Short getSweepTypeCode() { + return sweepTypeCode; + } + + public Short getTraceNumberOfSweepChannel() { + return traceNumberOfSweepChannel; + } + + public Short getSweepTraceTaperLengthStart() { + return sweepTraceTaperLengthStart; + } + + public Short getSweepTraceTaperLengthEnd() { + return sweepTraceTaperLengthEnd; + } + + public Short getTaperType() { + return taperType; + } + + public Short getCorrelatedDataTraces() { + return correlatedDataTraces; + } + + public Short getBinaryGainRecovered() { + return binaryGainRecovered; + } + + public Short getAmplitudeRecoveryMethod() { + return amplitudeRecoveryMethod; + } + + public Short getMeasurementSystem() { + return measurementSystem; + } + + public Short getImpulseSignalPolarity() { + return impulseSignalPolarity; + } + + public Short getVibratoryPolarityCode() { + return vibratoryPolarityCode; + } + + public Short getSEGYFormatRevisionNumber() { + return SEGYFormatRevisionNumber; + } + + public Short getFixedLengthTraceFlag() { + return fixedLengthTraceFlag; + } + + public Short getExtendedTextualFileHeader() { + return extendedTextualFileHeader; + } + + public void setTextualFileHeader(String textualFileHeader) { + this.textualFileHeader = textualFileHeader; + } + + public void setJobIdentificationNumber(Integer jobIdentificationNumber) { + this.jobIdentificationNumber = jobIdentificationNumber; + } + + public void setLineNumber(Integer lineNumber) { + LineNumber = lineNumber; + } + + public void setReelNumber(Integer reelNumber) { + ReelNumber = reelNumber; + } + + public void setDataTraces(Short dataTraces) { + this.dataTraces = dataTraces; + } + + public void setAuxiliaryTraces(Short auxiliaryTraces) { + this.auxiliaryTraces = auxiliaryTraces; + } + + public void setSampleIntervalInMicroseconds(Short sampleIntervalInMicroseconds) { + this.sampleIntervalInMicroseconds = sampleIntervalInMicroseconds; + } + + public void setSampleIntervalInMicrosecondsOriginal(Short sampleIntervalInMicrosecondsOriginal) { + this.sampleIntervalInMicrosecondsOriginal = sampleIntervalInMicrosecondsOriginal; + } + + public void setSamplesPerDataTrace(Short samplesPerDataTrace) { + this.samplesPerDataTrace = samplesPerDataTrace; + } + + public void setSamplesPerDataTraceOriginal(Short samplesPerDataTraceOriginal) { + this.samplesPerDataTraceOriginal = samplesPerDataTraceOriginal; + } + + public void setDataSampleFormatCode(Short dataSampleFormatCode) { + this.dataSampleFormatCode = dataSampleFormatCode; + } + + public void setEnsembleFold(Short ensembleFold) { + this.ensembleFold = ensembleFold; + } + + public void setTraceSortingCode(Short traceSortingCode) { + this.traceSortingCode = traceSortingCode; + } + + public void setVerticalSumCode(Short verticalSumCode) { + this.verticalSumCode = verticalSumCode; + } + + public void setSweepFrequencyAtStart(Short sweepFrequencyAtStart) { + this.sweepFrequencyAtStart = sweepFrequencyAtStart; + } + + public void setSweepFrequencyAtEnd(Short sweepFrequencyAtEnd) { + this.sweepFrequencyAtEnd = sweepFrequencyAtEnd; + } + + public void setSweepLength(Short sweepLength) { + this.sweepLength = sweepLength; + } + + public void setSweepTypeCode(Short sweepTypeCode) { + this.sweepTypeCode = sweepTypeCode; + } + + public void setTraceNumberOfSweepChannel(Short traceNumberOfSweepChannel) { + this.traceNumberOfSweepChannel = traceNumberOfSweepChannel; + } + + public void setSweepTraceTaperLengthStart(Short sweepTraceTaperLengthStart) { + this.sweepTraceTaperLengthStart = sweepTraceTaperLengthStart; + } + + public void setSweepTraceTaperLengthEnd(Short sweepTraceTaperLengthEnd) { + this.sweepTraceTaperLengthEnd = sweepTraceTaperLengthEnd; + } + + public void setTaperType(Short taperType) { + this.taperType = taperType; + } + + public void setCorrelatedDataTraces(Short correlatedDataTraces) { + this.correlatedDataTraces = correlatedDataTraces; + } + + public void setBinaryGainRecovered(Short binaryGainRecovered) { + this.binaryGainRecovered = binaryGainRecovered; + } + + public void setAmplitudeRecoveryMethod(Short amplitudeRecoveryMethod) { + this.amplitudeRecoveryMethod = amplitudeRecoveryMethod; + } + + public void setMeasurementSystem(Short measurementSystem) { + this.measurementSystem = measurementSystem; + } + + public void setImpulseSignalPolarity(Short impulseSignalPolarity) { + this.impulseSignalPolarity = impulseSignalPolarity; + } + + public void setVibratoryPolarityCode(Short vibratoryPolarityCode) { + this.vibratoryPolarityCode = vibratoryPolarityCode; + } + + public void setSEGYFormatRevisionNumber(Short SEGYFormatRevisionNumber) { + this.SEGYFormatRevisionNumber = SEGYFormatRevisionNumber; + } + + public void setFixedLengthTraceFlag(Short fixedLengthTraceFlag) { + this.fixedLengthTraceFlag = fixedLengthTraceFlag; + } + + public void setExtendedTextualFileHeader(Short extendedTextualFileHeader) { + this.extendedTextualFileHeader = extendedTextualFileHeader; + } + + @Override + public String toString() { + return "\n###文件头第一部分###\n" + + textualFileHeader + + "\n\n###文件头第二部分###" + + "\n作业标识号=" + jobIdentificationNumber + + "\n测线号=" + LineNumber + + "\n卷号=" + ReelNumber + + "\n每个道集的数据道数=" + dataTraces + + "\n每个道集的辅助道数=" + auxiliaryTraces + + "\n微秒(us)形式的采样间隔=" + sampleIntervalInMicroseconds + + "\n微秒(us)形式的原始野外记录采样间隔=" + sampleIntervalInMicrosecondsOriginal + + "\n数据道采样点数=" + samplesPerDataTrace + + "\n原始野外记录每道采样点数=" + samplesPerDataTraceOriginal + + "\n数据采样格式编码=" + dataSampleFormatCode + + "\n道集覆盖次数=" + ensembleFold + + "\n道分选码=" + traceSortingCode + + "\n垂直求和码=" + verticalSumCode + + "\n起始扫描频率(Hz)=" + sweepFrequencyAtStart + + "\n终止扫描频率(Hz)=" + sweepFrequencyAtEnd + + "\n扫描长度(ms)=" + sweepLength + + "\n扫描类型码=" + sweepTypeCode + + "\n扫描信道的道数=" + traceNumberOfSweepChannel + + "\n以毫秒表示的扫描道起始斜坡长度=" + sweepTraceTaperLengthStart + + "\n以毫秒表示的扫描道终止斜坡长度=" + sweepTraceTaperLengthEnd + + "\n斜坡类型=" + taperType + + "\n相关数据道=" + correlatedDataTraces + + "\n二进制增益恢复=" + binaryGainRecovered + + "\n振幅恢复方法=" + amplitudeRecoveryMethod + + "\n测量系统=" + measurementSystem + + "\n脉冲极化码=" + impulseSignalPolarity + + "\n可控源极化码=" + vibratoryPolarityCode + + "\nSEG Y格式修订版号=" + SEGYFormatRevisionNumber + + "\n固定长度道标志=" + fixedLengthTraceFlag + + "\n3200字节扩展原文文件头记录在二进制头后=" + extendedTextualFileHeader; + } +} diff --git a/src/pojo/entity/SEGY.java b/src/pojo/entity/SEGY.java new file mode 100644 index 0000000..06cab27 --- /dev/null +++ b/src/pojo/entity/SEGY.java @@ -0,0 +1,38 @@ +package pojo.entity; + +import java.util.Map; + +/** + * @author ZZHow + * @date 2024/11/25 + */ +public class SEGY { + // 文件头 + private FileHeader fileHeader; + // 数据体 + private Map dataBodies; + + public SEGY() { + } + + public SEGY(FileHeader fileHeader, Map dataBodies) { + this.fileHeader = fileHeader; + this.dataBodies = dataBodies; + } + + public FileHeader getFileHeader() { + return fileHeader; + } + + public Map getDataBodies() { + return dataBodies; + } + + public void setFileHeader(FileHeader fileHeader) { + this.fileHeader = fileHeader; + } + + public void setDataBodies(Map dataBodies) { + this.dataBodies = dataBodies; + } +} diff --git a/src/util/SEGYUtils.java b/src/util/SEGYUtils.java new file mode 100644 index 0000000..a7d364e --- /dev/null +++ b/src/util/SEGYUtils.java @@ -0,0 +1,302 @@ +package util; + +import pojo.entity.DataBody; +import pojo.entity.FileHeader; +import pojo.entity.SEGY; + +import java.io.*; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.HashMap; +import java.util.Map; + +/** + * @author ZZHow + * @date 2024/11/25 + */ +public class SEGYUtils { + + public static SEGY parseSEGY(String filePath) { + SEGY segy = new SEGY(); + + System.out.println("正在解析文件中,请稍后..."); + long start = System.currentTimeMillis(); + FileHeader fileHeader = SEGYUtils.parseFileHeader(filePath); + segy.setFileHeader(fileHeader); + Map longDataBodyMap = null; + longDataBodyMap = SEGYUtils.parseDataBody(filePath, fileHeader, false); + segy.setDataBodies(longDataBodyMap); + long end = System.currentTimeMillis(); + System.out.println("文件解析完成,耗时:" + (end - start) + "ms"); + System.out.println("文件共有 " + longDataBodyMap.keySet().size() + " 个数据道"); + + return segy; + } + + /** + * 解析 SEG Y 文件的的文件头 + * + * @param filePath SEG Y 文件路径 + * @return FileHeader + */ + public static FileHeader parseFileHeader(String filePath) { + File file = new File(filePath); + if (!file.exists()) { + System.out.println("文件不存在"); + + return null; + } + + return parseFileHeader(file); + } + + /** + * 解析 SEG Y 文件的的文件头 + * + * @param file SEG Y 文件 + * @return FileHeader + */ + public static FileHeader parseFileHeader(File file) { + FileHeader fileHeader = new FileHeader(); + + try (FileInputStream fileInputStream = new FileInputStream(file)) { + byte[] bytes = new byte[3200]; + fileInputStream.read(bytes, 0, bytes.length); + fileHeader.setTextualFileHeader(new String(bytes, "EBCDIC-CP-US")); + + bytes = new byte[400]; + fileInputStream.read(bytes, 0, bytes.length); + fileHeader.setJobIdentificationNumber(combineToInt(bytes[0], bytes[1], bytes[2], bytes[3])); + fileHeader.setLineNumber(combineToInt(bytes[4], bytes[5], bytes[6], bytes[7])); + fileHeader.setReelNumber(combineToInt(bytes[8], bytes[9], bytes[10], bytes[11])); + fileHeader.setDataTraces(combineToShort(bytes[12], bytes[13])); + fileHeader.setAuxiliaryTraces(combineToShort(bytes[14], bytes[15])); + fileHeader.setSampleIntervalInMicroseconds(combineToShort(bytes[16], bytes[17])); + fileHeader.setSampleIntervalInMicrosecondsOriginal(combineToShort(bytes[18], bytes[19])); + fileHeader.setSamplesPerDataTrace(combineToShort(bytes[20], bytes[21])); + fileHeader.setSamplesPerDataTraceOriginal(combineToShort(bytes[22], bytes[23])); + fileHeader.setDataSampleFormatCode(combineToShort(bytes[24], bytes[25])); + fileHeader.setEnsembleFold(combineToShort(bytes[26], bytes[27])); + fileHeader.setTraceSortingCode(combineToShort(bytes[28], bytes[29])); + fileHeader.setVerticalSumCode(combineToShort(bytes[30], bytes[31])); + fileHeader.setSweepFrequencyAtStart(combineToShort(bytes[32], bytes[33])); + fileHeader.setSweepFrequencyAtEnd(combineToShort(bytes[34], bytes[35])); + fileHeader.setSweepLength(combineToShort(bytes[36], bytes[37])); + fileHeader.setSweepTypeCode(combineToShort(bytes[38], bytes[39])); + fileHeader.setTraceNumberOfSweepChannel(combineToShort(bytes[40], bytes[41])); + fileHeader.setSweepTraceTaperLengthStart(combineToShort(bytes[42], bytes[43])); + fileHeader.setSweepTraceTaperLengthEnd(combineToShort(bytes[44], bytes[45])); + fileHeader.setTaperType(combineToShort(bytes[46], bytes[47])); + fileHeader.setCorrelatedDataTraces(combineToShort(bytes[48], bytes[49])); + fileHeader.setBinaryGainRecovered(combineToShort(bytes[50], bytes[51])); + fileHeader.setAmplitudeRecoveryMethod(combineToShort(bytes[52], bytes[53])); + fileHeader.setMeasurementSystem(combineToShort(bytes[54], bytes[55])); + fileHeader.setImpulseSignalPolarity(combineToShort(bytes[56], bytes[57])); + fileHeader.setVibratoryPolarityCode(combineToShort(bytes[58], bytes[59])); + fileHeader.setSEGYFormatRevisionNumber(combineToShort(bytes[300], bytes[301])); + fileHeader.setFixedLengthTraceFlag(combineToShort(bytes[302], bytes[303])); + fileHeader.setExtendedTextualFileHeader(combineToShort(bytes[304], bytes[305])); + } catch (IOException e) { + e.printStackTrace(); + } + + return fileHeader; + } + + /** + * 解析 SEG Y 文件的的数据体 + * + * @param file SEG Y 文件 + * @return DataBody + */ + public static Map parseDataBody(File file, FileHeader fileHeader, boolean processDisplay) { + return parseDataBody(file.getAbsolutePath(), fileHeader, processDisplay); + } + + /** + * 解析 SEG Y 文件的数据体 + * + * @param filePath SEG Y 文件路径 + * @return DataBody + */ + public static Map parseDataBody(String filePath, FileHeader fileHeader, boolean processDisplay) { + Map dataBodyMap = new HashMap<>(); + + try (RandomAccessFile file = new RandomAccessFile(filePath, "r")) { + long cnt = 0; + file.seek(3600L); // 跳过文件头 3600 bytes + + while (file.getFilePointer() < file.length()) { + cnt++; + if (processDisplay) + System.out.println("++第 " + cnt + " 数据道++"); + DataBody dataBody = new DataBody(); + byte[] bytes = new byte[240]; + file.read(bytes, 0, bytes.length); + ByteBuffer buffer = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN); + + dataBody.setTraceSequenceNumberWithinLine(buffer.getInt()); + dataBody.setTraceSequenceNumberWithinSEGY(buffer.getInt()); + dataBody.setOriginalFieldRecordNumber(buffer.getInt()); + dataBody.setTraceNumberWithinTheOriginal(buffer.getInt()); + dataBody.setEnergySourcePointNumber(buffer.getInt()); + dataBody.setEnsembleNumber(buffer.getInt()); + dataBody.setTraceNumberWithinTheEnsemble(buffer.getInt()); + dataBody.setTraceIdentificationCode(buffer.getShort()); + dataBody.setVerticallySummedTraces(buffer.getShort()); + dataBody.setHorizontallyStackedTraces(buffer.getShort()); + dataBody.setDataUse(buffer.getShort()); + dataBody.setSourcePointToReceiverGroup(buffer.getInt()); + dataBody.setReceiverGroupElevation(buffer.getInt()); + dataBody.setSurfaceElevationAtSource(buffer.getInt()); + dataBody.setSourceDepthBelowSurface(buffer.getInt()); + dataBody.setDatumElevationAtReceiverGroup(buffer.getInt()); + dataBody.setDatumElevationAtSource(buffer.getInt()); + dataBody.setWaterDepthAtSource(buffer.getInt()); + dataBody.setWaterDepthAtGroup(buffer.getInt()); + dataBody.setScalar1(buffer.getShort()); + dataBody.setScalar2(buffer.getShort()); + dataBody.setSourceCoordinateX(buffer.getInt()); + dataBody.setSourceCoordinateY(buffer.getInt()); + dataBody.setGroupCoordinateX(buffer.getInt()); + dataBody.setGroupCoordinateY(buffer.getInt()); + dataBody.setCoordinateUnits(buffer.getShort()); + dataBody.setWeatheringVelocity(buffer.getShort()); + dataBody.setSubweatheringVelocity(buffer.getShort()); + dataBody.setUpholeTimeAtSourceInMilliseconds(buffer.getShort()); + dataBody.setUpholeTimeAtGroupInMilliseconds(buffer.getShort()); + dataBody.setSourceStaticCorrectionInMilliseconds(buffer.getShort()); + dataBody.setGroupStaticCorrectionInMilliseconds(buffer.getShort()); + dataBody.setTotalStaticAppliedInMilliseconds(buffer.getShort()); + dataBody.setLagTimeA(buffer.getShort()); + dataBody.setLagTimeB(buffer.getShort()); + dataBody.setDelayRecordingTime(buffer.getShort()); + dataBody.setMuteTimeStart(buffer.getShort()); + dataBody.setMuteTimeEnd(buffer.getShort()); + dataBody.setNumberOfSamplesInThisTrace(buffer.getShort()); + dataBody.setSampleIntervalInMicroseconds(buffer.getShort()); + dataBody.setGainTypeOfFieldInstruments(buffer.getShort()); + dataBody.setInstrumentGainConstant(buffer.getShort()); + dataBody.setInstrumentEarlyOrInitialGain(buffer.getShort()); + dataBody.setCorrelated(buffer.getShort()); + dataBody.setSweepFrequencyAtStart(buffer.getShort()); + dataBody.setSweepFrequencyAtEnd(buffer.getShort()); + dataBody.setSweepLengthInMilliseconds(buffer.getShort()); + dataBody.setSweepType(buffer.getShort()); + dataBody.setSweepTraceTaperLengthAtStart(buffer.getShort()); + dataBody.setSweepTraceTaperLengthAtEnd(buffer.getShort()); + dataBody.setTaperType(buffer.getShort()); + dataBody.setAliasFilterFrequency(buffer.getShort()); + dataBody.setAliasFilterSlope(buffer.getShort()); + dataBody.setNotchFilterFrequency(buffer.getShort()); + dataBody.setNotchFilterSlope(buffer.getShort()); + dataBody.setLowCutFrequency(buffer.getShort()); + dataBody.setHighCutFrequency(buffer.getShort()); + dataBody.setLowCutSlope(buffer.getShort()); + dataBody.setHighCutSlope(buffer.getShort()); + dataBody.setYearDataRecorded(buffer.getShort()); + dataBody.setDayOfYear(buffer.getShort()); + dataBody.setHourOfDay(buffer.getShort()); + dataBody.setMinuteOfHour(buffer.getShort()); + dataBody.setSecondOfMinute(buffer.getShort()); + dataBody.setTimeBasisCode(buffer.getShort()); + dataBody.setTraceWeightingFactor(buffer.getShort()); + dataBody.setRollSwitchPositionOne(buffer.getShort()); + dataBody.setTraceNumberOneWithinOriginal(buffer.getShort()); + dataBody.setLastTraceWithinOriginal(buffer.getShort()); + dataBody.setGapSize(buffer.getShort()); + dataBody.setOverTravelAssociated(buffer.getShort()); + dataBody.setxCoordinateOfEnsemble(buffer.getInt()); + dataBody.setyCoordinateOfEnsemble(buffer.getInt()); + dataBody.setInLineNumber(buffer.getInt()); + dataBody.setCrossLineNumber(buffer.getInt()); + dataBody.setShotpointNumber(buffer.getInt()); + dataBody.setScalar3(buffer.getShort()); + dataBody.setTraceValueMeasurementUnit(buffer.getShort()); + dataBody.setTransductionConstant(get6BytesAsLong(buffer)); + dataBody.setTransductionUnits(buffer.getShort()); + dataBody.setDeviceTraceIdentifier(buffer.getShort()); + dataBody.setScalar4(buffer.getShort()); + dataBody.setSourceTypeOrientation(buffer.getShort()); + dataBody.setSourceEnergyDirection(get6BytesAsLong(buffer)); + dataBody.setSourceMeasurement(get6BytesAsLong(buffer)); + dataBody.setSourceMeasurementUnit(buffer.getShort()); + + // 处理数据体第二部分 + float[] floats = new float[dataBody.getNumberOfSamplesInThisTrace()]; + for (int i = 0; i < dataBody.getNumberOfSamplesInThisTrace(); i++) { + switch (fileHeader.getDataSampleFormatCode()) { + case 1: // IBM浮点数 + floats[i] = convertIbmToFloat(file.readInt()); + break; + case 5: // IEEE浮点数 + floats[i] = file.readFloat(); + break; + case 3: // 16位整型 + floats[i] = file.readShort(); + break; + default: + throw new UnsupportedOperationException("Unsupported format code: " + fileHeader.getDataSampleFormatCode()); + } + } + dataBody.setSamplingData(floats); + + dataBodyMap.put(cnt, dataBody); + + if (processDisplay) + System.out.println(dataBody); + } + } catch (IOException e) { + e.printStackTrace(); + } + + return dataBodyMap; + } + + private static long combineToLong(byte a, byte b, byte c, byte d, byte e, byte f) { + long res = 0; + res += (long) a << 40; + res += (long) b << 32; + res += c << 24; + res += d << 16; + res += e << 8; + res += f; + + return res; + } + + private static int combineToInt(byte a, byte b, byte c, byte d) { + int res = 0; + res += a << 24; + res += b << 16; + res += c << 8; + res += d; + + return res; + } + + private static short combineToShort(byte a, byte b) { + short res = 0; + res += (short) (a << 8); + res += b; + + return res; + } + + // IBM浮点数转换 (实现参考 SEGY 规范) + private static float convertIbmToFloat(int ibmFloat) { + int sign = ((ibmFloat >> 31) == 0) ? 1 : -1; + int exponent = ((ibmFloat >> 24) & 0x7F) - 64; + int mantissa = (ibmFloat & 0x00FFFFFF); + return (float) (sign * mantissa * Math.pow(16, exponent - 6)); + } + + private static long get6BytesAsLong(ByteBuffer buffer) { + // 读取6字节,按大端序拼接 + long value = 0; + for (int i = 0; i < 6; i++) { + value = (value << 8) | (buffer.get() & 0xFF); + } + return value; + } +}