From 0415a3748508efaddcf4b7470f044cc1e16d5156 Mon Sep 17 00:00:00 2001 From: ZZHow <109335896+ZZHow1024@users.noreply.github.com> Date: Mon, 25 Nov 2024 20:06:31 +0800 Subject: [PATCH 01/10] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE 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. From 20b98fed4515ec2ca9cc9ac01d1a7640c0601023 Mon Sep 17 00:00:00 2001 From: ZZHow <109335896+ZZHow1024@users.noreply.github.com> Date: Mon, 25 Nov 2024 20:14:02 +0800 Subject: [PATCH 02/10] feat: parse SEGY file header --- .gitignore | 34 +++ src/Main.java | 16 ++ src/pojo/entity/FileHeader.java | 365 ++++++++++++++++++++++++++++++++ src/util/SEGYUtils.java | 113 ++++++++++ 4 files changed, 528 insertions(+) create mode 100644 .gitignore create mode 100644 src/Main.java create mode 100644 src/pojo/entity/FileHeader.java create mode 100644 src/util/SEGYUtils.java 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/src/Main.java b/src/Main.java new file mode 100644 index 0000000..2bf7d99 --- /dev/null +++ b/src/Main.java @@ -0,0 +1,16 @@ +import pojo.entity.FileHeader; +import util.SEGYUtils; + +/** + * @author ZZHow + * @date 2024/11/25 + */ +public class Main { + public static void main(String[] args) { + // String filePath = args[0]; + String filePath = ""; + + FileHeader fileHeader = SEGYUtils.parseFileHeader(filePath); + System.out.println(fileHeader); + } +} \ No newline at end of file diff --git a/src/pojo/entity/FileHeader.java b/src/pojo/entity/FileHeader.java new file mode 100644 index 0000000..b6914ac --- /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" + + 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/util/SEGYUtils.java b/src/util/SEGYUtils.java new file mode 100644 index 0000000..bdeccdc --- /dev/null +++ b/src/util/SEGYUtils.java @@ -0,0 +1,113 @@ +package util; + +import pojo.entity.DataBody; +import pojo.entity.FileHeader; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +/** + * @author ZZHow + * @date 2024/11/25 + */ +public class SEGYUtils { + + /** + * 解析 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 DataBody parseDataBody(File file) { + return null; + } + + 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; + } +} From ca79bf18cd40acdeea46d402a620f281f1bad1ee Mon Sep 17 00:00:00 2001 From: ZZHow <109335896+ZZHow1024@users.noreply.github.com> Date: Mon, 25 Nov 2024 23:24:13 +0800 Subject: [PATCH 03/10] feat: parse a trace from SEGY file data --- src/Main.java | 5 + src/pojo/entity/DataBody.java | 978 ++++++++++++++++++++++++++++++++ src/pojo/entity/FileHeader.java | 2 +- src/util/SEGYUtils.java | 140 ++++- 4 files changed, 1122 insertions(+), 3 deletions(-) create mode 100644 src/pojo/entity/DataBody.java diff --git a/src/Main.java b/src/Main.java index 2bf7d99..3948c62 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,3 +1,4 @@ +import pojo.entity.DataBody; import pojo.entity.FileHeader; import util.SEGYUtils; @@ -12,5 +13,9 @@ public static void main(String[] args) { FileHeader fileHeader = SEGYUtils.parseFileHeader(filePath); System.out.println(fileHeader); + + // 当前仅支持读一组数据道 + DataBody dataBody = SEGYUtils.parseDataBody(filePath, fileHeader); + System.out.println(dataBody); } } \ 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..b3fe9f8 --- /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 byte[] 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 byte[] 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(byte[] 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 index b6914ac..3fba622 100644 --- a/src/pojo/entity/FileHeader.java +++ b/src/pojo/entity/FileHeader.java @@ -328,7 +328,7 @@ public void setExtendedTextualFileHeader(Short extendedTextualFileHeader) { @Override public String toString() { - return "###文件头第一部分###\n" + + return "\n###文件头第一部分###\n" + textualFileHeader + "\n\n###文件头第二部分###" + "\n作业标识号=" + jobIdentificationNumber + diff --git a/src/util/SEGYUtils.java b/src/util/SEGYUtils.java index bdeccdc..ff6920e 100644 --- a/src/util/SEGYUtils.java +++ b/src/util/SEGYUtils.java @@ -83,14 +83,150 @@ public static FileHeader parseFileHeader(File file) { return fileHeader; } + /** + * 解析 SEG Y 文件的的数据体 + * + * @param filePath SEG Y 文件路径 + * @return DataBody + */ + public static DataBody parseDataBody(String filePath, FileHeader fileHeader) { + File file = new File(filePath); + if (!file.exists()) { + System.out.println("文件不存在"); + + return null; + } + + return parseDataBody(file, fileHeader); + } + /** * 解析 SEG Y 文件的数据体 * * @param file SEG Y 文件 * @return DataBody */ - public static DataBody parseDataBody(File file) { - return null; + public static DataBody parseDataBody(File file, FileHeader fileHeader) { + DataBody dataBody = new DataBody(); + + try (FileInputStream fileInputStream = new FileInputStream(file)) { + fileInputStream.skip(3600); + + byte[] bytes = new byte[240]; + fileInputStream.read(bytes, 0, bytes.length); + + dataBody.setTraceSequenceNumberWithinLine(combineToInt(bytes[0], bytes[1], bytes[2], bytes[3])); + dataBody.setTraceSequenceNumberWithinSEGY(combineToInt(bytes[4], bytes[5], bytes[6], bytes[7])); + dataBody.setOriginalFieldRecordNumber(combineToInt(bytes[8], bytes[9], bytes[10], bytes[11])); + dataBody.setTraceNumberWithinTheOriginal(combineToInt(bytes[12], bytes[13], bytes[14], bytes[15])); + dataBody.setEnergySourcePointNumber(combineToInt(bytes[16], bytes[17], bytes[18], bytes[19])); + dataBody.setEnsembleNumber(combineToInt(bytes[20], bytes[21], bytes[22], bytes[23])); + dataBody.setTraceNumberWithinTheEnsemble(combineToInt(bytes[24], bytes[25], bytes[26], bytes[27])); + dataBody.setTraceIdentificationCode(combineToShort(bytes[28], bytes[29])); + dataBody.setVerticallySummedTraces(combineToShort(bytes[30], bytes[31])); + dataBody.setHorizontallyStackedTraces(combineToShort(bytes[32], bytes[33])); + dataBody.setDataUse(combineToShort(bytes[34], bytes[35])); + dataBody.setSourcePointToReceiverGroup(combineToInt(bytes[36], bytes[37], bytes[38], bytes[39])); + dataBody.setReceiverGroupElevation(combineToInt(bytes[40], bytes[41], bytes[42], bytes[43])); + dataBody.setSurfaceElevationAtSource(combineToInt(bytes[44], bytes[45], bytes[46], bytes[47])); + dataBody.setSourceDepthBelowSurface(combineToInt(bytes[48], bytes[49], bytes[50], bytes[51])); + dataBody.setDatumElevationAtReceiverGroup(combineToInt(bytes[52], bytes[53], bytes[54], bytes[55])); + dataBody.setDatumElevationAtSource(combineToInt(bytes[56], bytes[57], bytes[58], bytes[59])); + dataBody.setWaterDepthAtSource(combineToInt(bytes[60], bytes[61], bytes[62], bytes[63])); + dataBody.setWaterDepthAtGroup(combineToInt(bytes[64], bytes[65], bytes[66], bytes[67])); + dataBody.setScalar1(combineToShort(bytes[68], bytes[69])); + dataBody.setScalar2(combineToShort(bytes[70], bytes[71])); + dataBody.setSourceCoordinateX(combineToInt(bytes[72], bytes[73], bytes[74], bytes[75])); + dataBody.setSourceCoordinateY(combineToInt(bytes[76], bytes[77], bytes[78], bytes[79])); + dataBody.setGroupCoordinateX(combineToInt(bytes[80], bytes[81], bytes[82], bytes[83])); + dataBody.setGroupCoordinateY(combineToInt(bytes[84], bytes[85], bytes[86], bytes[87])); + dataBody.setCoordinateUnits(combineToShort(bytes[88], bytes[89])); + dataBody.setWeatheringVelocity(combineToShort(bytes[90], bytes[91])); + dataBody.setSubweatheringVelocity(combineToShort(bytes[92], bytes[93])); + dataBody.setUpholeTimeAtSourceInMilliseconds(combineToShort(bytes[94], bytes[95])); + dataBody.setUpholeTimeAtGroupInMilliseconds(combineToShort(bytes[96], bytes[97])); + dataBody.setSourceStaticCorrectionInMilliseconds(combineToShort(bytes[98], bytes[99])); + dataBody.setGroupStaticCorrectionInMilliseconds(combineToShort(bytes[100], bytes[101])); + dataBody.setTotalStaticAppliedInMilliseconds(combineToShort(bytes[102], bytes[103])); + dataBody.setLagTimeA(combineToShort(bytes[104], bytes[105])); + dataBody.setLagTimeB(combineToShort(bytes[106], bytes[107])); + dataBody.setDelayRecordingTime(combineToShort(bytes[108], bytes[109])); + dataBody.setMuteTimeStart(combineToShort(bytes[110], bytes[111])); + dataBody.setMuteTimeEnd(combineToShort(bytes[112], bytes[113])); + dataBody.setNumberOfSamplesInThisTrace(combineToShort(bytes[114], bytes[115])); + dataBody.setSampleIntervalInMicroseconds(combineToShort(bytes[116], bytes[117])); + dataBody.setGainTypeOfFieldInstruments(combineToShort(bytes[118], bytes[119])); + dataBody.setInstrumentGainConstant(combineToShort(bytes[120], bytes[121])); + dataBody.setInstrumentEarlyOrInitialGain(combineToShort(bytes[122], bytes[123])); + dataBody.setCorrelated(combineToShort(bytes[124], bytes[125])); + dataBody.setSweepFrequencyAtStart(combineToShort(bytes[126], bytes[127])); + dataBody.setSweepFrequencyAtEnd(combineToShort(bytes[128], bytes[129])); + dataBody.setSweepLengthInMilliseconds(combineToShort(bytes[130], bytes[131])); + dataBody.setSweepType(combineToShort(bytes[132], bytes[133])); + dataBody.setSweepTraceTaperLengthAtStart(combineToShort(bytes[134], bytes[135])); + dataBody.setSweepTraceTaperLengthAtEnd(combineToShort(bytes[136], bytes[137])); + dataBody.setTaperType(combineToShort(bytes[138], bytes[139])); + dataBody.setAliasFilterFrequency(combineToShort(bytes[140], bytes[141])); + dataBody.setAliasFilterSlope(combineToShort(bytes[142], bytes[143])); + dataBody.setNotchFilterFrequency(combineToShort(bytes[144], bytes[145])); + dataBody.setNotchFilterSlope(combineToShort(bytes[146], bytes[147])); + dataBody.setLowCutFrequency(combineToShort(bytes[148], bytes[149])); + dataBody.setHighCutFrequency(combineToShort(bytes[150], bytes[151])); + dataBody.setLowCutSlope(combineToShort(bytes[152], bytes[153])); + dataBody.setHighCutSlope(combineToShort(bytes[154], bytes[155])); + dataBody.setYearDataRecorded(combineToShort(bytes[156], bytes[157])); + dataBody.setDayOfYear(combineToShort(bytes[158], bytes[159])); + dataBody.setHourOfDay(combineToShort(bytes[160], bytes[161])); + dataBody.setMinuteOfHour(combineToShort(bytes[162], bytes[163])); + dataBody.setSecondOfMinute(combineToShort(bytes[164], bytes[165])); + dataBody.setTimeBasisCode(combineToShort(bytes[166], bytes[167])); + dataBody.setTraceWeightingFactor(combineToShort(bytes[168], bytes[169])); + dataBody.setRollSwitchPositionOne(combineToShort(bytes[170], bytes[171])); + dataBody.setTraceNumberOneWithinOriginal(combineToShort(bytes[172], bytes[173])); + dataBody.setLastTraceWithinOriginal(combineToShort(bytes[174], bytes[175])); + dataBody.setGapSize(combineToShort(bytes[176], bytes[177])); + dataBody.setOverTravelAssociated(combineToShort(bytes[178], bytes[179])); + dataBody.setxCoordinateOfEnsemble(combineToInt(bytes[180], bytes[181], bytes[182], bytes[183])); + dataBody.setyCoordinateOfEnsemble(combineToInt(bytes[184], bytes[185], bytes[186], bytes[187])); + dataBody.setInLineNumber(combineToInt(bytes[188], bytes[189], bytes[190], bytes[191])); + dataBody.setCrossLineNumber(combineToInt(bytes[192], bytes[193], bytes[194], bytes[195])); + dataBody.setShotpointNumber(combineToInt(bytes[196], bytes[197], bytes[198], bytes[199])); + dataBody.setScalar3(combineToShort(bytes[200], bytes[201])); + dataBody.setTraceValueMeasurementUnit(combineToShort(bytes[202], bytes[203])); + dataBody.setTransductionConstant(combineToLong(bytes[204], bytes[205], bytes[206], bytes[207], bytes[208], bytes[209])); + dataBody.setTransductionUnits(combineToShort(bytes[210], bytes[211])); + dataBody.setDeviceTraceIdentifier(combineToShort(bytes[212], bytes[213])); + dataBody.setScalar4(combineToShort(bytes[214], bytes[215])); + dataBody.setSourceTypeOrientation(combineToShort(bytes[216], bytes[217])); + dataBody.setSourceEnergyDirection(combineToLong(bytes[218], bytes[219], bytes[220], bytes[221], bytes[222], bytes[223])); + dataBody.setSourceMeasurement(combineToLong(bytes[224], bytes[225], bytes[226], bytes[227], bytes[228], bytes[229])); + dataBody.setSourceMeasurementUnit(combineToShort(bytes[230], bytes[232])); + + int len = fileHeader.getSamplesPerDataTraceOriginal(); + switch (fileHeader.getDataSampleFormatCode()) { + case 1, 2, 4, 5 -> len *= 4; + case 3 -> len *= 2; + } + bytes = new byte[len]; + fileInputStream.read(bytes, 0, bytes.length); + dataBody.setSamplingData(bytes); + } catch (IOException e) { + e.printStackTrace(); + } + + return dataBody; + } + + private static long combineToLong(byte a, byte b, byte c, byte d, byte e, long 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) { From df8e4811eab2500ae5460039e455f216aabc58ba Mon Sep 17 00:00:00 2001 From: ZZHow <109335896+ZZHow1024@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:05:13 +0800 Subject: [PATCH 04/10] docx: update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0d7a785..ecfb32e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# MagicSEGY -MagicSEGY.Developing with Java. +# ZSEGY +ZSEGY.Developing with Java. From 53e5bf0e99b7e3e0b236028237fbba8256f29dc3 Mon Sep 17 00:00:00 2001 From: ZZHow <109335896+ZZHow1024@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:05:50 +0800 Subject: [PATCH 05/10] feat: parse all traces from SEGY file data --- src/Main.java | 6 +- src/util/SEGYUtils.java | 215 +++++++++++++++++++++------------------- 2 files changed, 117 insertions(+), 104 deletions(-) diff --git a/src/Main.java b/src/Main.java index 3948c62..33a0a27 100644 --- a/src/Main.java +++ b/src/Main.java @@ -2,6 +2,8 @@ import pojo.entity.FileHeader; import util.SEGYUtils; +import java.util.Map; + /** * @author ZZHow * @date 2024/11/25 @@ -14,8 +16,6 @@ public static void main(String[] args) { FileHeader fileHeader = SEGYUtils.parseFileHeader(filePath); System.out.println(fileHeader); - // 当前仅支持读一组数据道 - DataBody dataBody = SEGYUtils.parseDataBody(filePath, fileHeader); - System.out.println(dataBody); + Map longDataBodyMap = SEGYUtils.parseDataBody(filePath, fileHeader); } } \ No newline at end of file diff --git a/src/util/SEGYUtils.java b/src/util/SEGYUtils.java index ff6920e..d464a0f 100644 --- a/src/util/SEGYUtils.java +++ b/src/util/SEGYUtils.java @@ -6,6 +6,10 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * @author ZZHow @@ -89,7 +93,7 @@ public static FileHeader parseFileHeader(File file) { * @param filePath SEG Y 文件路径 * @return DataBody */ - public static DataBody parseDataBody(String filePath, FileHeader fileHeader) { + public static Map parseDataBody(String filePath, FileHeader fileHeader) { File file = new File(filePath); if (!file.exists()) { System.out.println("文件不存在"); @@ -106,115 +110,124 @@ public static DataBody parseDataBody(String filePath, FileHeader fileHeader) { * @param file SEG Y 文件 * @return DataBody */ - public static DataBody parseDataBody(File file, FileHeader fileHeader) { - DataBody dataBody = new DataBody(); + public static Map parseDataBody(File file, FileHeader fileHeader) { + Map dataBodyMap = new HashMap<>(); try (FileInputStream fileInputStream = new FileInputStream(file)) { - fileInputStream.skip(3600); + long cnt = 0; + fileInputStream.skip(3600); // 跳过文件头 3600 bytes - byte[] bytes = new byte[240]; - fileInputStream.read(bytes, 0, bytes.length); + while (fileInputStream.available() > 0) { + cnt++; + System.out.println("++第 " + cnt + " 数据道++"); + DataBody dataBody = new DataBody(); + byte[] bytes = new byte[240]; + fileInputStream.read(bytes, 0, bytes.length); + + dataBody.setTraceSequenceNumberWithinLine(combineToInt(bytes[0], bytes[1], bytes[2], bytes[3])); + dataBody.setTraceSequenceNumberWithinSEGY(combineToInt(bytes[4], bytes[5], bytes[6], bytes[7])); + dataBody.setOriginalFieldRecordNumber(combineToInt(bytes[8], bytes[9], bytes[10], bytes[11])); + dataBody.setTraceNumberWithinTheOriginal(combineToInt(bytes[12], bytes[13], bytes[14], bytes[15])); + dataBody.setEnergySourcePointNumber(combineToInt(bytes[16], bytes[17], bytes[18], bytes[19])); + dataBody.setEnsembleNumber(combineToInt(bytes[20], bytes[21], bytes[22], bytes[23])); + dataBody.setTraceNumberWithinTheEnsemble(combineToInt(bytes[24], bytes[25], bytes[26], bytes[27])); + dataBody.setTraceIdentificationCode(combineToShort(bytes[28], bytes[29])); + dataBody.setVerticallySummedTraces(combineToShort(bytes[30], bytes[31])); + dataBody.setHorizontallyStackedTraces(combineToShort(bytes[32], bytes[33])); + dataBody.setDataUse(combineToShort(bytes[34], bytes[35])); + dataBody.setSourcePointToReceiverGroup(combineToInt(bytes[36], bytes[37], bytes[38], bytes[39])); + dataBody.setReceiverGroupElevation(combineToInt(bytes[40], bytes[41], bytes[42], bytes[43])); + dataBody.setSurfaceElevationAtSource(combineToInt(bytes[44], bytes[45], bytes[46], bytes[47])); + dataBody.setSourceDepthBelowSurface(combineToInt(bytes[48], bytes[49], bytes[50], bytes[51])); + dataBody.setDatumElevationAtReceiverGroup(combineToInt(bytes[52], bytes[53], bytes[54], bytes[55])); + dataBody.setDatumElevationAtSource(combineToInt(bytes[56], bytes[57], bytes[58], bytes[59])); + dataBody.setWaterDepthAtSource(combineToInt(bytes[60], bytes[61], bytes[62], bytes[63])); + dataBody.setWaterDepthAtGroup(combineToInt(bytes[64], bytes[65], bytes[66], bytes[67])); + dataBody.setScalar1(combineToShort(bytes[68], bytes[69])); + dataBody.setScalar2(combineToShort(bytes[70], bytes[71])); + dataBody.setSourceCoordinateX(combineToInt(bytes[72], bytes[73], bytes[74], bytes[75])); + dataBody.setSourceCoordinateY(combineToInt(bytes[76], bytes[77], bytes[78], bytes[79])); + dataBody.setGroupCoordinateX(combineToInt(bytes[80], bytes[81], bytes[82], bytes[83])); + dataBody.setGroupCoordinateY(combineToInt(bytes[84], bytes[85], bytes[86], bytes[87])); + dataBody.setCoordinateUnits(combineToShort(bytes[88], bytes[89])); + dataBody.setWeatheringVelocity(combineToShort(bytes[90], bytes[91])); + dataBody.setSubweatheringVelocity(combineToShort(bytes[92], bytes[93])); + dataBody.setUpholeTimeAtSourceInMilliseconds(combineToShort(bytes[94], bytes[95])); + dataBody.setUpholeTimeAtGroupInMilliseconds(combineToShort(bytes[96], bytes[97])); + dataBody.setSourceStaticCorrectionInMilliseconds(combineToShort(bytes[98], bytes[99])); + dataBody.setGroupStaticCorrectionInMilliseconds(combineToShort(bytes[100], bytes[101])); + dataBody.setTotalStaticAppliedInMilliseconds(combineToShort(bytes[102], bytes[103])); + dataBody.setLagTimeA(combineToShort(bytes[104], bytes[105])); + dataBody.setLagTimeB(combineToShort(bytes[106], bytes[107])); + dataBody.setDelayRecordingTime(combineToShort(bytes[108], bytes[109])); + dataBody.setMuteTimeStart(combineToShort(bytes[110], bytes[111])); + dataBody.setMuteTimeEnd(combineToShort(bytes[112], bytes[113])); + dataBody.setNumberOfSamplesInThisTrace(combineToShort(bytes[114], bytes[115])); + dataBody.setSampleIntervalInMicroseconds(combineToShort(bytes[116], bytes[117])); + dataBody.setGainTypeOfFieldInstruments(combineToShort(bytes[118], bytes[119])); + dataBody.setInstrumentGainConstant(combineToShort(bytes[120], bytes[121])); + dataBody.setInstrumentEarlyOrInitialGain(combineToShort(bytes[122], bytes[123])); + dataBody.setCorrelated(combineToShort(bytes[124], bytes[125])); + dataBody.setSweepFrequencyAtStart(combineToShort(bytes[126], bytes[127])); + dataBody.setSweepFrequencyAtEnd(combineToShort(bytes[128], bytes[129])); + dataBody.setSweepLengthInMilliseconds(combineToShort(bytes[130], bytes[131])); + dataBody.setSweepType(combineToShort(bytes[132], bytes[133])); + dataBody.setSweepTraceTaperLengthAtStart(combineToShort(bytes[134], bytes[135])); + dataBody.setSweepTraceTaperLengthAtEnd(combineToShort(bytes[136], bytes[137])); + dataBody.setTaperType(combineToShort(bytes[138], bytes[139])); + dataBody.setAliasFilterFrequency(combineToShort(bytes[140], bytes[141])); + dataBody.setAliasFilterSlope(combineToShort(bytes[142], bytes[143])); + dataBody.setNotchFilterFrequency(combineToShort(bytes[144], bytes[145])); + dataBody.setNotchFilterSlope(combineToShort(bytes[146], bytes[147])); + dataBody.setLowCutFrequency(combineToShort(bytes[148], bytes[149])); + dataBody.setHighCutFrequency(combineToShort(bytes[150], bytes[151])); + dataBody.setLowCutSlope(combineToShort(bytes[152], bytes[153])); + dataBody.setHighCutSlope(combineToShort(bytes[154], bytes[155])); + dataBody.setYearDataRecorded(combineToShort(bytes[156], bytes[157])); + dataBody.setDayOfYear(combineToShort(bytes[158], bytes[159])); + dataBody.setHourOfDay(combineToShort(bytes[160], bytes[161])); + dataBody.setMinuteOfHour(combineToShort(bytes[162], bytes[163])); + dataBody.setSecondOfMinute(combineToShort(bytes[164], bytes[165])); + dataBody.setTimeBasisCode(combineToShort(bytes[166], bytes[167])); + dataBody.setTraceWeightingFactor(combineToShort(bytes[168], bytes[169])); + dataBody.setRollSwitchPositionOne(combineToShort(bytes[170], bytes[171])); + dataBody.setTraceNumberOneWithinOriginal(combineToShort(bytes[172], bytes[173])); + dataBody.setLastTraceWithinOriginal(combineToShort(bytes[174], bytes[175])); + dataBody.setGapSize(combineToShort(bytes[176], bytes[177])); + dataBody.setOverTravelAssociated(combineToShort(bytes[178], bytes[179])); + dataBody.setxCoordinateOfEnsemble(combineToInt(bytes[180], bytes[181], bytes[182], bytes[183])); + dataBody.setyCoordinateOfEnsemble(combineToInt(bytes[184], bytes[185], bytes[186], bytes[187])); + dataBody.setInLineNumber(combineToInt(bytes[188], bytes[189], bytes[190], bytes[191])); + dataBody.setCrossLineNumber(combineToInt(bytes[192], bytes[193], bytes[194], bytes[195])); + dataBody.setShotpointNumber(combineToInt(bytes[196], bytes[197], bytes[198], bytes[199])); + dataBody.setScalar3(combineToShort(bytes[200], bytes[201])); + dataBody.setTraceValueMeasurementUnit(combineToShort(bytes[202], bytes[203])); + dataBody.setTransductionConstant(combineToLong(bytes[204], bytes[205], bytes[206], bytes[207], bytes[208], bytes[209])); + dataBody.setTransductionUnits(combineToShort(bytes[210], bytes[211])); + dataBody.setDeviceTraceIdentifier(combineToShort(bytes[212], bytes[213])); + dataBody.setScalar4(combineToShort(bytes[214], bytes[215])); + dataBody.setSourceTypeOrientation(combineToShort(bytes[216], bytes[217])); + dataBody.setSourceEnergyDirection(combineToLong(bytes[218], bytes[219], bytes[220], bytes[221], bytes[222], bytes[223])); + dataBody.setSourceMeasurement(combineToLong(bytes[224], bytes[225], bytes[226], bytes[227], bytes[228], bytes[229])); + dataBody.setSourceMeasurementUnit(combineToShort(bytes[230], bytes[232])); - dataBody.setTraceSequenceNumberWithinLine(combineToInt(bytes[0], bytes[1], bytes[2], bytes[3])); - dataBody.setTraceSequenceNumberWithinSEGY(combineToInt(bytes[4], bytes[5], bytes[6], bytes[7])); - dataBody.setOriginalFieldRecordNumber(combineToInt(bytes[8], bytes[9], bytes[10], bytes[11])); - dataBody.setTraceNumberWithinTheOriginal(combineToInt(bytes[12], bytes[13], bytes[14], bytes[15])); - dataBody.setEnergySourcePointNumber(combineToInt(bytes[16], bytes[17], bytes[18], bytes[19])); - dataBody.setEnsembleNumber(combineToInt(bytes[20], bytes[21], bytes[22], bytes[23])); - dataBody.setTraceNumberWithinTheEnsemble(combineToInt(bytes[24], bytes[25], bytes[26], bytes[27])); - dataBody.setTraceIdentificationCode(combineToShort(bytes[28], bytes[29])); - dataBody.setVerticallySummedTraces(combineToShort(bytes[30], bytes[31])); - dataBody.setHorizontallyStackedTraces(combineToShort(bytes[32], bytes[33])); - dataBody.setDataUse(combineToShort(bytes[34], bytes[35])); - dataBody.setSourcePointToReceiverGroup(combineToInt(bytes[36], bytes[37], bytes[38], bytes[39])); - dataBody.setReceiverGroupElevation(combineToInt(bytes[40], bytes[41], bytes[42], bytes[43])); - dataBody.setSurfaceElevationAtSource(combineToInt(bytes[44], bytes[45], bytes[46], bytes[47])); - dataBody.setSourceDepthBelowSurface(combineToInt(bytes[48], bytes[49], bytes[50], bytes[51])); - dataBody.setDatumElevationAtReceiverGroup(combineToInt(bytes[52], bytes[53], bytes[54], bytes[55])); - dataBody.setDatumElevationAtSource(combineToInt(bytes[56], bytes[57], bytes[58], bytes[59])); - dataBody.setWaterDepthAtSource(combineToInt(bytes[60], bytes[61], bytes[62], bytes[63])); - dataBody.setWaterDepthAtGroup(combineToInt(bytes[64], bytes[65], bytes[66], bytes[67])); - dataBody.setScalar1(combineToShort(bytes[68], bytes[69])); - dataBody.setScalar2(combineToShort(bytes[70], bytes[71])); - dataBody.setSourceCoordinateX(combineToInt(bytes[72], bytes[73], bytes[74], bytes[75])); - dataBody.setSourceCoordinateY(combineToInt(bytes[76], bytes[77], bytes[78], bytes[79])); - dataBody.setGroupCoordinateX(combineToInt(bytes[80], bytes[81], bytes[82], bytes[83])); - dataBody.setGroupCoordinateY(combineToInt(bytes[84], bytes[85], bytes[86], bytes[87])); - dataBody.setCoordinateUnits(combineToShort(bytes[88], bytes[89])); - dataBody.setWeatheringVelocity(combineToShort(bytes[90], bytes[91])); - dataBody.setSubweatheringVelocity(combineToShort(bytes[92], bytes[93])); - dataBody.setUpholeTimeAtSourceInMilliseconds(combineToShort(bytes[94], bytes[95])); - dataBody.setUpholeTimeAtGroupInMilliseconds(combineToShort(bytes[96], bytes[97])); - dataBody.setSourceStaticCorrectionInMilliseconds(combineToShort(bytes[98], bytes[99])); - dataBody.setGroupStaticCorrectionInMilliseconds(combineToShort(bytes[100], bytes[101])); - dataBody.setTotalStaticAppliedInMilliseconds(combineToShort(bytes[102], bytes[103])); - dataBody.setLagTimeA(combineToShort(bytes[104], bytes[105])); - dataBody.setLagTimeB(combineToShort(bytes[106], bytes[107])); - dataBody.setDelayRecordingTime(combineToShort(bytes[108], bytes[109])); - dataBody.setMuteTimeStart(combineToShort(bytes[110], bytes[111])); - dataBody.setMuteTimeEnd(combineToShort(bytes[112], bytes[113])); - dataBody.setNumberOfSamplesInThisTrace(combineToShort(bytes[114], bytes[115])); - dataBody.setSampleIntervalInMicroseconds(combineToShort(bytes[116], bytes[117])); - dataBody.setGainTypeOfFieldInstruments(combineToShort(bytes[118], bytes[119])); - dataBody.setInstrumentGainConstant(combineToShort(bytes[120], bytes[121])); - dataBody.setInstrumentEarlyOrInitialGain(combineToShort(bytes[122], bytes[123])); - dataBody.setCorrelated(combineToShort(bytes[124], bytes[125])); - dataBody.setSweepFrequencyAtStart(combineToShort(bytes[126], bytes[127])); - dataBody.setSweepFrequencyAtEnd(combineToShort(bytes[128], bytes[129])); - dataBody.setSweepLengthInMilliseconds(combineToShort(bytes[130], bytes[131])); - dataBody.setSweepType(combineToShort(bytes[132], bytes[133])); - dataBody.setSweepTraceTaperLengthAtStart(combineToShort(bytes[134], bytes[135])); - dataBody.setSweepTraceTaperLengthAtEnd(combineToShort(bytes[136], bytes[137])); - dataBody.setTaperType(combineToShort(bytes[138], bytes[139])); - dataBody.setAliasFilterFrequency(combineToShort(bytes[140], bytes[141])); - dataBody.setAliasFilterSlope(combineToShort(bytes[142], bytes[143])); - dataBody.setNotchFilterFrequency(combineToShort(bytes[144], bytes[145])); - dataBody.setNotchFilterSlope(combineToShort(bytes[146], bytes[147])); - dataBody.setLowCutFrequency(combineToShort(bytes[148], bytes[149])); - dataBody.setHighCutFrequency(combineToShort(bytes[150], bytes[151])); - dataBody.setLowCutSlope(combineToShort(bytes[152], bytes[153])); - dataBody.setHighCutSlope(combineToShort(bytes[154], bytes[155])); - dataBody.setYearDataRecorded(combineToShort(bytes[156], bytes[157])); - dataBody.setDayOfYear(combineToShort(bytes[158], bytes[159])); - dataBody.setHourOfDay(combineToShort(bytes[160], bytes[161])); - dataBody.setMinuteOfHour(combineToShort(bytes[162], bytes[163])); - dataBody.setSecondOfMinute(combineToShort(bytes[164], bytes[165])); - dataBody.setTimeBasisCode(combineToShort(bytes[166], bytes[167])); - dataBody.setTraceWeightingFactor(combineToShort(bytes[168], bytes[169])); - dataBody.setRollSwitchPositionOne(combineToShort(bytes[170], bytes[171])); - dataBody.setTraceNumberOneWithinOriginal(combineToShort(bytes[172], bytes[173])); - dataBody.setLastTraceWithinOriginal(combineToShort(bytes[174], bytes[175])); - dataBody.setGapSize(combineToShort(bytes[176], bytes[177])); - dataBody.setOverTravelAssociated(combineToShort(bytes[178], bytes[179])); - dataBody.setxCoordinateOfEnsemble(combineToInt(bytes[180], bytes[181], bytes[182], bytes[183])); - dataBody.setyCoordinateOfEnsemble(combineToInt(bytes[184], bytes[185], bytes[186], bytes[187])); - dataBody.setInLineNumber(combineToInt(bytes[188], bytes[189], bytes[190], bytes[191])); - dataBody.setCrossLineNumber(combineToInt(bytes[192], bytes[193], bytes[194], bytes[195])); - dataBody.setShotpointNumber(combineToInt(bytes[196], bytes[197], bytes[198], bytes[199])); - dataBody.setScalar3(combineToShort(bytes[200], bytes[201])); - dataBody.setTraceValueMeasurementUnit(combineToShort(bytes[202], bytes[203])); - dataBody.setTransductionConstant(combineToLong(bytes[204], bytes[205], bytes[206], bytes[207], bytes[208], bytes[209])); - dataBody.setTransductionUnits(combineToShort(bytes[210], bytes[211])); - dataBody.setDeviceTraceIdentifier(combineToShort(bytes[212], bytes[213])); - dataBody.setScalar4(combineToShort(bytes[214], bytes[215])); - dataBody.setSourceTypeOrientation(combineToShort(bytes[216], bytes[217])); - dataBody.setSourceEnergyDirection(combineToLong(bytes[218], bytes[219], bytes[220], bytes[221], bytes[222], bytes[223])); - dataBody.setSourceMeasurement(combineToLong(bytes[224], bytes[225], bytes[226], bytes[227], bytes[228], bytes[229])); - dataBody.setSourceMeasurementUnit(combineToShort(bytes[230], bytes[232])); - - int len = fileHeader.getSamplesPerDataTraceOriginal(); - switch (fileHeader.getDataSampleFormatCode()) { - case 1, 2, 4, 5 -> len *= 4; - case 3 -> len *= 2; + int len = fileHeader.getSamplesPerDataTraceOriginal(); + switch (fileHeader.getDataSampleFormatCode()) { + case 1, 2, 4, 5 -> len *= 4; + case 3 -> len *= 2; + } + bytes = new byte[len]; + fileInputStream.read(bytes, 0, bytes.length); + dataBody.setSamplingData(bytes); + + dataBodyMap.put(cnt, dataBody); + System.out.println(dataBody); } - bytes = new byte[len]; - fileInputStream.read(bytes, 0, bytes.length); - dataBody.setSamplingData(bytes); } catch (IOException e) { e.printStackTrace(); } - return dataBody; + return dataBodyMap; } private static long combineToLong(byte a, byte b, byte c, byte d, byte e, long f) { From 4ce251ccd20cfd41cd52f7db291b40ed23216e22 Mon Sep 17 00:00:00 2001 From: ZZHow <109335896+ZZHow1024@users.noreply.github.com> Date: Tue, 26 Nov 2024 18:29:18 +0800 Subject: [PATCH 06/10] fix: resolve trace parsing issue in SEGY file --- src/Main.java | 65 +++++++- src/pojo/entity/DataBody.java | 6 +- src/pojo/entity/SEGY.java | 38 +++++ src/util/SEGYUtils.java | 274 +++++++++++++++++++--------------- 4 files changed, 257 insertions(+), 126 deletions(-) create mode 100644 src/pojo/entity/SEGY.java diff --git a/src/Main.java b/src/Main.java index 33a0a27..cb0d127 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,8 +1,8 @@ -import pojo.entity.DataBody; -import pojo.entity.FileHeader; +import pojo.entity.SEGY; import util.SEGYUtils; -import java.util.Map; +import java.io.File; +import java.util.Scanner; /** * @author ZZHow @@ -10,12 +10,65 @@ */ public class Main { public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + SEGY segy = new SEGY(); // String filePath = args[0]; String filePath = ""; - FileHeader fileHeader = SEGYUtils.parseFileHeader(filePath); - System.out.println(fileHeader); - Map longDataBodyMap = SEGYUtils.parseDataBody(filePath, fileHeader); + // 程序主界面 + 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("无效输入"); + } + } + op = scanner.next(); + } } } \ No newline at end of file diff --git a/src/pojo/entity/DataBody.java b/src/pojo/entity/DataBody.java index b3fe9f8..3c1442d 100644 --- a/src/pojo/entity/DataBody.java +++ b/src/pojo/entity/DataBody.java @@ -183,7 +183,7 @@ public class DataBody { // 233-240:未赋值――为任选信息预留 /**/ - private byte[] samplingData; + private float[] samplingData; public DataBody() { } @@ -532,7 +532,7 @@ public Short getSourceMeasurementUnit() { return sourceMeasurementUnit; } - public byte[] getSamplingData() { + public float[] getSamplingData() { return samplingData; } @@ -880,7 +880,7 @@ public void setSourceMeasurementUnit(Short sourceMeasurementUnit) { this.sourceMeasurementUnit = sourceMeasurementUnit; } - public void setSamplingData(byte[] samplingData) { + public void setSamplingData(float[] samplingData) { this.samplingData = samplingData; } 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 index d464a0f..a7d364e 100644 --- a/src/util/SEGYUtils.java +++ b/src/util/SEGYUtils.java @@ -2,13 +2,12 @@ import pojo.entity.DataBody; import pojo.entity.FileHeader; +import pojo.entity.SEGY; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.ArrayList; +import java.io.*; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -17,6 +16,23 @@ */ 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 文件的的文件头 * @@ -90,138 +106,145 @@ public static FileHeader parseFileHeader(File file) { /** * 解析 SEG Y 文件的的数据体 * - * @param filePath SEG Y 文件路径 + * @param file SEG Y 文件 * @return DataBody */ - public static Map parseDataBody(String filePath, FileHeader fileHeader) { - File file = new File(filePath); - if (!file.exists()) { - System.out.println("文件不存在"); - - return null; - } - - return parseDataBody(file, fileHeader); + public static Map parseDataBody(File file, FileHeader fileHeader, boolean processDisplay) { + return parseDataBody(file.getAbsolutePath(), fileHeader, processDisplay); } /** * 解析 SEG Y 文件的数据体 * - * @param file SEG Y 文件 + * @param filePath SEG Y 文件路径 * @return DataBody */ - public static Map parseDataBody(File file, FileHeader fileHeader) { + public static Map parseDataBody(String filePath, FileHeader fileHeader, boolean processDisplay) { Map dataBodyMap = new HashMap<>(); - try (FileInputStream fileInputStream = new FileInputStream(file)) { + try (RandomAccessFile file = new RandomAccessFile(filePath, "r")) { long cnt = 0; - fileInputStream.skip(3600); // 跳过文件头 3600 bytes + file.seek(3600L); // 跳过文件头 3600 bytes - while (fileInputStream.available() > 0) { + while (file.getFilePointer() < file.length()) { cnt++; - System.out.println("++第 " + cnt + " 数据道++"); + if (processDisplay) + System.out.println("++第 " + cnt + " 数据道++"); DataBody dataBody = new DataBody(); byte[] bytes = new byte[240]; - fileInputStream.read(bytes, 0, bytes.length); + file.read(bytes, 0, bytes.length); + ByteBuffer buffer = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN); - dataBody.setTraceSequenceNumberWithinLine(combineToInt(bytes[0], bytes[1], bytes[2], bytes[3])); - dataBody.setTraceSequenceNumberWithinSEGY(combineToInt(bytes[4], bytes[5], bytes[6], bytes[7])); - dataBody.setOriginalFieldRecordNumber(combineToInt(bytes[8], bytes[9], bytes[10], bytes[11])); - dataBody.setTraceNumberWithinTheOriginal(combineToInt(bytes[12], bytes[13], bytes[14], bytes[15])); - dataBody.setEnergySourcePointNumber(combineToInt(bytes[16], bytes[17], bytes[18], bytes[19])); - dataBody.setEnsembleNumber(combineToInt(bytes[20], bytes[21], bytes[22], bytes[23])); - dataBody.setTraceNumberWithinTheEnsemble(combineToInt(bytes[24], bytes[25], bytes[26], bytes[27])); - dataBody.setTraceIdentificationCode(combineToShort(bytes[28], bytes[29])); - dataBody.setVerticallySummedTraces(combineToShort(bytes[30], bytes[31])); - dataBody.setHorizontallyStackedTraces(combineToShort(bytes[32], bytes[33])); - dataBody.setDataUse(combineToShort(bytes[34], bytes[35])); - dataBody.setSourcePointToReceiverGroup(combineToInt(bytes[36], bytes[37], bytes[38], bytes[39])); - dataBody.setReceiverGroupElevation(combineToInt(bytes[40], bytes[41], bytes[42], bytes[43])); - dataBody.setSurfaceElevationAtSource(combineToInt(bytes[44], bytes[45], bytes[46], bytes[47])); - dataBody.setSourceDepthBelowSurface(combineToInt(bytes[48], bytes[49], bytes[50], bytes[51])); - dataBody.setDatumElevationAtReceiverGroup(combineToInt(bytes[52], bytes[53], bytes[54], bytes[55])); - dataBody.setDatumElevationAtSource(combineToInt(bytes[56], bytes[57], bytes[58], bytes[59])); - dataBody.setWaterDepthAtSource(combineToInt(bytes[60], bytes[61], bytes[62], bytes[63])); - dataBody.setWaterDepthAtGroup(combineToInt(bytes[64], bytes[65], bytes[66], bytes[67])); - dataBody.setScalar1(combineToShort(bytes[68], bytes[69])); - dataBody.setScalar2(combineToShort(bytes[70], bytes[71])); - dataBody.setSourceCoordinateX(combineToInt(bytes[72], bytes[73], bytes[74], bytes[75])); - dataBody.setSourceCoordinateY(combineToInt(bytes[76], bytes[77], bytes[78], bytes[79])); - dataBody.setGroupCoordinateX(combineToInt(bytes[80], bytes[81], bytes[82], bytes[83])); - dataBody.setGroupCoordinateY(combineToInt(bytes[84], bytes[85], bytes[86], bytes[87])); - dataBody.setCoordinateUnits(combineToShort(bytes[88], bytes[89])); - dataBody.setWeatheringVelocity(combineToShort(bytes[90], bytes[91])); - dataBody.setSubweatheringVelocity(combineToShort(bytes[92], bytes[93])); - dataBody.setUpholeTimeAtSourceInMilliseconds(combineToShort(bytes[94], bytes[95])); - dataBody.setUpholeTimeAtGroupInMilliseconds(combineToShort(bytes[96], bytes[97])); - dataBody.setSourceStaticCorrectionInMilliseconds(combineToShort(bytes[98], bytes[99])); - dataBody.setGroupStaticCorrectionInMilliseconds(combineToShort(bytes[100], bytes[101])); - dataBody.setTotalStaticAppliedInMilliseconds(combineToShort(bytes[102], bytes[103])); - dataBody.setLagTimeA(combineToShort(bytes[104], bytes[105])); - dataBody.setLagTimeB(combineToShort(bytes[106], bytes[107])); - dataBody.setDelayRecordingTime(combineToShort(bytes[108], bytes[109])); - dataBody.setMuteTimeStart(combineToShort(bytes[110], bytes[111])); - dataBody.setMuteTimeEnd(combineToShort(bytes[112], bytes[113])); - dataBody.setNumberOfSamplesInThisTrace(combineToShort(bytes[114], bytes[115])); - dataBody.setSampleIntervalInMicroseconds(combineToShort(bytes[116], bytes[117])); - dataBody.setGainTypeOfFieldInstruments(combineToShort(bytes[118], bytes[119])); - dataBody.setInstrumentGainConstant(combineToShort(bytes[120], bytes[121])); - dataBody.setInstrumentEarlyOrInitialGain(combineToShort(bytes[122], bytes[123])); - dataBody.setCorrelated(combineToShort(bytes[124], bytes[125])); - dataBody.setSweepFrequencyAtStart(combineToShort(bytes[126], bytes[127])); - dataBody.setSweepFrequencyAtEnd(combineToShort(bytes[128], bytes[129])); - dataBody.setSweepLengthInMilliseconds(combineToShort(bytes[130], bytes[131])); - dataBody.setSweepType(combineToShort(bytes[132], bytes[133])); - dataBody.setSweepTraceTaperLengthAtStart(combineToShort(bytes[134], bytes[135])); - dataBody.setSweepTraceTaperLengthAtEnd(combineToShort(bytes[136], bytes[137])); - dataBody.setTaperType(combineToShort(bytes[138], bytes[139])); - dataBody.setAliasFilterFrequency(combineToShort(bytes[140], bytes[141])); - dataBody.setAliasFilterSlope(combineToShort(bytes[142], bytes[143])); - dataBody.setNotchFilterFrequency(combineToShort(bytes[144], bytes[145])); - dataBody.setNotchFilterSlope(combineToShort(bytes[146], bytes[147])); - dataBody.setLowCutFrequency(combineToShort(bytes[148], bytes[149])); - dataBody.setHighCutFrequency(combineToShort(bytes[150], bytes[151])); - dataBody.setLowCutSlope(combineToShort(bytes[152], bytes[153])); - dataBody.setHighCutSlope(combineToShort(bytes[154], bytes[155])); - dataBody.setYearDataRecorded(combineToShort(bytes[156], bytes[157])); - dataBody.setDayOfYear(combineToShort(bytes[158], bytes[159])); - dataBody.setHourOfDay(combineToShort(bytes[160], bytes[161])); - dataBody.setMinuteOfHour(combineToShort(bytes[162], bytes[163])); - dataBody.setSecondOfMinute(combineToShort(bytes[164], bytes[165])); - dataBody.setTimeBasisCode(combineToShort(bytes[166], bytes[167])); - dataBody.setTraceWeightingFactor(combineToShort(bytes[168], bytes[169])); - dataBody.setRollSwitchPositionOne(combineToShort(bytes[170], bytes[171])); - dataBody.setTraceNumberOneWithinOriginal(combineToShort(bytes[172], bytes[173])); - dataBody.setLastTraceWithinOriginal(combineToShort(bytes[174], bytes[175])); - dataBody.setGapSize(combineToShort(bytes[176], bytes[177])); - dataBody.setOverTravelAssociated(combineToShort(bytes[178], bytes[179])); - dataBody.setxCoordinateOfEnsemble(combineToInt(bytes[180], bytes[181], bytes[182], bytes[183])); - dataBody.setyCoordinateOfEnsemble(combineToInt(bytes[184], bytes[185], bytes[186], bytes[187])); - dataBody.setInLineNumber(combineToInt(bytes[188], bytes[189], bytes[190], bytes[191])); - dataBody.setCrossLineNumber(combineToInt(bytes[192], bytes[193], bytes[194], bytes[195])); - dataBody.setShotpointNumber(combineToInt(bytes[196], bytes[197], bytes[198], bytes[199])); - dataBody.setScalar3(combineToShort(bytes[200], bytes[201])); - dataBody.setTraceValueMeasurementUnit(combineToShort(bytes[202], bytes[203])); - dataBody.setTransductionConstant(combineToLong(bytes[204], bytes[205], bytes[206], bytes[207], bytes[208], bytes[209])); - dataBody.setTransductionUnits(combineToShort(bytes[210], bytes[211])); - dataBody.setDeviceTraceIdentifier(combineToShort(bytes[212], bytes[213])); - dataBody.setScalar4(combineToShort(bytes[214], bytes[215])); - dataBody.setSourceTypeOrientation(combineToShort(bytes[216], bytes[217])); - dataBody.setSourceEnergyDirection(combineToLong(bytes[218], bytes[219], bytes[220], bytes[221], bytes[222], bytes[223])); - dataBody.setSourceMeasurement(combineToLong(bytes[224], bytes[225], bytes[226], bytes[227], bytes[228], bytes[229])); - dataBody.setSourceMeasurementUnit(combineToShort(bytes[230], bytes[232])); + 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()); - int len = fileHeader.getSamplesPerDataTraceOriginal(); - switch (fileHeader.getDataSampleFormatCode()) { - case 1, 2, 4, 5 -> len *= 4; - case 3 -> len *= 2; + // 处理数据体第二部分 + 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()); + } } - bytes = new byte[len]; - fileInputStream.read(bytes, 0, bytes.length); - dataBody.setSamplingData(bytes); + dataBody.setSamplingData(floats); dataBodyMap.put(cnt, dataBody); - System.out.println(dataBody); + + if (processDisplay) + System.out.println(dataBody); } } catch (IOException e) { e.printStackTrace(); @@ -230,7 +253,7 @@ public static Map parseDataBody(File file, FileHeader fileHeader return dataBodyMap; } - private static long combineToLong(byte a, byte b, byte c, byte d, byte e, long f) { + 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; @@ -259,4 +282,21 @@ private static short combineToShort(byte a, byte 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; + } } From 26479b8741be06664dc316a0683306ce837148cc Mon Sep 17 00:00:00 2001 From: ZZHow <109335896+ZZHow1024@users.noreply.github.com> Date: Tue, 26 Nov 2024 21:54:24 +0800 Subject: [PATCH 07/10] feat: add command pattern implementation --- src/META-INF/MANIFEST.MF | 3 ++ src/Main.java | 60 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 src/META-INF/MANIFEST.MF 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 index cb0d127..09a64a8 100644 --- a/src/Main.java +++ b/src/Main.java @@ -12,10 +12,66 @@ public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); SEGY segy = new SEGY(); - // String filePath = args[0]; String filePath = ""; + System.out.println("ZSEGY 1.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("第 " + 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; + } + System.out.println("正在解析中..."); + segy = SEGYUtils.parseSEGY(args[2]); + System.out.println(segy.getFileHeader()); + System.out.println("第 " + 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 使用说明 ---"); + 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. 展示文件头"); @@ -68,7 +124,9 @@ public static void main(String[] args) { System.out.println("无效输入"); } } + System.out.print("->"); op = scanner.next(); + scanner.nextLine(); } } } \ No newline at end of file From 90f239a0cc2eb9d9e9cba2b3964efd097b728987 Mon Sep 17 00:00:00 2001 From: ZZHow <109335896+ZZHow1024@users.noreply.github.com> Date: Tue, 26 Nov 2024 21:59:37 +0800 Subject: [PATCH 08/10] fix: update and correct text prompts --- src/Main.java | 5 ++--- src/pojo/entity/DataBody.java | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Main.java b/src/Main.java index 09a64a8..9a6f880 100644 --- a/src/Main.java +++ b/src/Main.java @@ -34,7 +34,7 @@ public static void main(String[] args) { System.exit(0);; } segy = SEGYUtils.parseSEGY(args[2]); - System.out.println("第 " + num + " 个数据道:"); + System.out.println("\n@@@第 " + num + " 个数据道@@@"); System.out.println(segy.getDataBodies().get(num)); System.exit(0); } @@ -46,10 +46,9 @@ public static void main(String[] args) { System.out.println("输入格式错误,输入 -help 查看提示"); break; } - System.out.println("正在解析中..."); segy = SEGYUtils.parseSEGY(args[2]); System.out.println(segy.getFileHeader()); - System.out.println("第 " + num + " 个数据道:"); + System.out.println("\n@@@第 " + num + " 个数据道@@@"); System.out.println(segy.getDataBodies().get(num)); System.exit(0); } diff --git a/src/pojo/entity/DataBody.java b/src/pojo/entity/DataBody.java index 3c1442d..c3b5a16 100644 --- a/src/pojo/entity/DataBody.java +++ b/src/pojo/entity/DataBody.java @@ -886,7 +886,7 @@ public void setSamplingData(float[] samplingData) { @Override public String toString() { - return "\n###数据体第一部分###" + + return "\n###数据道第一部分###" + "\n测线中道顺序号=" + traceSequenceNumberWithinLine + "\nSEG Y文件中道顺序号=" + traceSequenceNumberWithinSEGY + "\n野外原始记录号=" + originalFieldRecordNumber + @@ -973,6 +973,6 @@ public String toString() { "\n相对震源方位的震源能量方向=" + sourceEnergyDirection + "\n震源测量=" + sourceMeasurement + "\n震源测量单位=" + sourceMeasurementUnit + - "\n\n###数据体第二部分###\n" + Arrays.toString(samplingData); + "\n\n###数据道第二部分###\n" + Arrays.toString(samplingData); } } From 869106749bce965f5ad270d243d44c457294270c Mon Sep 17 00:00:00 2001 From: ZZHow <109335896+ZZHow1024@users.noreply.github.com> Date: Tue, 26 Nov 2024 22:51:27 +0800 Subject: [PATCH 09/10] chore: update version number --- src/Main.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Main.java b/src/Main.java index 9a6f880..31b57af 100644 --- a/src/Main.java +++ b/src/Main.java @@ -14,7 +14,7 @@ public static void main(String[] args) { SEGY segy = new SEGY(); String filePath = ""; - System.out.println("ZSEGY 1.0"); + System.out.println("ZSEGY 1.0.0"); System.out.println("Author: ZZHow"); if (args.length != 0) { @@ -56,7 +56,7 @@ public static void main(String[] args) { filePath = args[1]; } case "-help", "help" -> { - System.out.println("--- ZSEGY 1.0 使用说明 ---"); + 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]:解析并输出文件头"); From 6622b7eb5c813864cc016b64c44e4824a9eca47c Mon Sep 17 00:00:00 2001 From: ZZHow <109335896+ZZHow1024@users.noreply.github.com> Date: Tue, 26 Nov 2024 23:02:52 +0800 Subject: [PATCH 10/10] docx: update README --- README.md | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ecfb32e..03e04b1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,65 @@ -# ZSEGY -ZSEGY.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