diff --git a/cmd/parse.go b/cmd/parse.go index b98102d..41811aa 100644 --- a/cmd/parse.go +++ b/cmd/parse.go @@ -24,6 +24,7 @@ var parseCmd = &cobra.Command{ // p.ParseAuxPlatformWithHead("demo/ref/辅助数据.dat") fmt.Println("Reference Time: 2000-01-01 12:00:00 UTC, seconds:", extract.Time2000UTCSec()) p.ParseAuxPlatform("demo/output/SJY01_051622_S96_PLAT.AUX") + p.ParseAuxEBox("demo/output/SJY01_051622_S96_EB.AUX") }, } diff --git a/extract/aux.go b/extract/aux.go index 7cd10e5..ae48cfc 100644 --- a/extract/aux.go +++ b/extract/aux.go @@ -6,7 +6,6 @@ import ( "fmt" "math" "os" - "path/filepath" "strings" "time" @@ -116,9 +115,24 @@ func (e *Extractor) SeprateAuxAndImgData(dataFile string, segmentIndex int) erro log.Info("seprate aux and img data from", dataFile) - name := filepath.Base(dataFile) - name = strings.TrimRight(name, filepath.Ext(name)) + dataLen := len(data) + log.Info("length of original data: ", dataLen) + var firstFrmHead *AuxFrameHead + data, firstFrmHead = e.trimImgRawData(data) + dataLen = len(data) + log.Info("after trim,length of data: ", dataLen) + e.quanlityAnalysis(data) + outputDir := e.params.OutputPath + name := strings.Join([]string{ + e.params.Satellite, + "PMS", + time.Unix(int64(firstFrmHead.TimeSec)+int64(ReferenceTime2000), + int64(firstFrmHead.TimeSecFrac)*1000). + Format("20060102_150405"), + e.params.DataId, + fmt.Sprintf("%03d", firstFrmHead.FileNo), + }, "_") lw := newL0Writer(outputDir, name) defer lw.Close() @@ -126,13 +140,6 @@ func (e *Extractor) SeprateAuxAndImgData(dataFile string, segmentIndex int) erro var panEnviHdr, mssEnviHdr EnviHdr var afh AuxFrameHead - dataLen := len(data) - log.Info("length of original data: ", dataLen) - data = e.trimImgRawData(data) - dataLen = len(data) - log.Info("length of trimmed data: ", dataLen) - - e.quanlityAnalysis(data) msdata := make([][]byte, 4) @@ -281,9 +288,9 @@ func (e *Extractor) quanlityAnalysis(data []byte) { } // 裁剪图像数据,只保留有效数据 -func (e *Extractor) trimImgRawData(data []byte) []byte { +func (e *Extractor) trimImgRawData(data []byte) ([]byte, *AuxFrameHead) { var start, end int - + afh := &AuxFrameHead{} // 将中心辅助数据时间合理的帧作为第一帧 var startAuxLine bool for i := 0; i < len(data); { @@ -300,7 +307,6 @@ func (e *Extractor) trimImgRawData(data []byte) []byte { continue } - afh := &AuxFrameHead{} afh.Decode(data[i : i+24]) if !afh.IsValidFrmHead { @@ -322,5 +328,5 @@ func (e *Extractor) trimImgRawData(data []byte) []byte { } } - return data[start:end] + return data[start:end], afh } diff --git a/extract/aux_ebox.go b/extract/aux_ebox.go index 4f25529..7cc22e0 100644 --- a/extract/aux_ebox.go +++ b/extract/aux_ebox.go @@ -1,6 +1,12 @@ package extract -import "fmt" +import ( + "fmt" + "os" + + "github.com/k0kubun/pp/v3" + "github.com/sirupsen/logrus" +) // 卫星时间起点 北京时间 2000-01-01 20:00:00 var ( @@ -9,23 +15,64 @@ var ( // 焦面电箱辅助数据 128 字节 (每 16 行原始图像数据为一组) type AuxFocalBox struct { - TransferTime float32 // 执行转移时间 0.5us/bit - TrainingDone byte // 1B成功;0B失败 - WorkMode byte // 工作模式 0B正常;1B故障 - IntegralDirection byte // 积分方向 1B正向;0B反向 - PGAGain byte // PGA增益 + TransferTime float32 // 执行转移时间 0.5us/bit + TrainingDone byte // 1B成功;0B失败 + WorkMode byte // 工作模式 0B正常;1B故障 + IntegralDirection byte // 积分方向 1B正向;0B反向 + PGAGain byte // PGA增益 + PIntegrationLevel uint8 // [5]P波积分级数 + B1IntegrationLevel uint8 // [6.(7~6)]B1积分级数 + B2IntegrationLevel uint8 // [6.(5~4)]B2积分级数 + B3IntegrationLevel uint8 // [6.(3~2)]B3积分级数 + B4IntegrationLevel uint8 // [6.(1~0)]B4积分级数 + SecPluseState byte // [7.(7)]秒脉冲状态 0x1 成功;0x0 失败 + DarkFieldBias uint16 // [7.(5~0)-8] 暗场偏置 1DN/bit,十六进制无符号整型数 + PWinAddr uint16 // [9-10]全色开窗地址 + B1WinAddr uint16 // [11-12]B1开窗地址 + B2WinAddr uint16 // [13-14]B2开窗地址 + B3WinAddr uint16 // [15-16]B3开窗地址 + B4WinAddr uint16 // [17-18]B4开窗地址 + CCDWorkMode byte // [38]工作模式 00H=TDI推扫;11H=框幅; + RawDiskAvailableCap uint16 // [39-40]原始磁盘可用存储容量 量纲:2MBytes/bit + ZipDiskAvailableCap uint16 // [41-42]压缩盘可用存储容量 + CommandCount uint8 // [53]指令计数器 + LastCommandCode uint8 // [54]最后指令代码 } func (ab *AuxFocalBox) Decode(data []byte) error { + if len(data) < 128 { + return fmt.Errorf("eletric box aux data length error") + } byte0 := data[0] & 0b00111111 ab.TransferTime = float32(uint32(byte0)<<16|uint32(data[1])<<8|uint32(data[2])) * 0.5 ab.TrainingDone = data[3] & 0b10000000 ab.WorkMode = data[3] & 0b01000000 ab.IntegralDirection = data[3] & 0b00100000 ab.PGAGain = data[3] & 0b00011111 + ab.PIntegrationLevel = data[4] + ab.B1IntegrationLevel = data[5] >> 6 & 0x03 + ab.B2IntegrationLevel = data[5] >> 4 & 0x03 + ab.B3IntegrationLevel = data[5] >> 2 & 0x03 + ab.B4IntegrationLevel = data[5] & 0x03 + ab.SecPluseState = data[6] >> 7 & 0x01 + ab.DarkFieldBias = uint16(data[6]&0x3f)<<8 | uint16(data[7]) + ab.PWinAddr = uint16(data[8])<<8 | uint16(data[9]) + ab.B1WinAddr = uint16(data[10])<<8 | uint16(data[11]) + ab.B2WinAddr = uint16(data[12])<<8 | uint16(data[13]) + ab.B3WinAddr = uint16(data[14])<<8 | uint16(data[15]) + ab.B4WinAddr = uint16(data[16])<<8 | uint16(data[17]) + ab.CCDWorkMode = data[37] + ab.RawDiskAvailableCap = (uint16(data[38])<<8 | uint16(data[39])) * 2 + ab.ZipDiskAvailableCap = (uint16(data[40])<<8 | uint16(data[41])) * 2 + ab.CommandCount = data[52] + ab.LastCommandCode = data[53] return nil } +func (ab AuxFocalBox) Print() { + pp.Println(ab) +} + func (ab AuxFocalBox) String() string { return fmt.Sprintf( `执行转移时间:%f us\n @@ -92,3 +139,24 @@ func (ab AuxFocalBox) PGAGainValue() string { return "unknown" } } + +func (e *Extractor) ParseAuxEBox(auxfile string) ([]*AuxFocalBox, error) { + data, err := os.ReadFile(auxfile) + if err != nil { + logrus.Println("read aux data from", auxfile, "error:", err.Error()) + return nil, err + } + + var afs []*AuxFocalBox + for i := 0; i < len(data); i += 128 { + var ab AuxFocalBox + if err := ab.Decode(data[i : i+128]); err != nil { + return nil, err + } + afs = append(afs, &ab) + + ab.Print() + break + } + return afs, nil +} diff --git a/extract/aux_platform.go b/extract/aux_platform.go index 1f9d739..39c9c1f 100644 --- a/extract/aux_platform.go +++ b/extract/aux_platform.go @@ -322,9 +322,9 @@ func (ap *AuxPlatform) Parse(data []byte) error { ap.MemsGyroXAV = float64(bigEndianToInt32(data[479:483])) * 0.000001 ap.MemsGyroYAV = float64(bigEndianToInt32(data[483:487])) * 0.000001 ap.MemsGyroZAV = float64(bigEndianToInt32(data[487:491])) * 0.000001 - ap.MagnetictrengthX = float64(bigEndianToInt32(data[491:495])) * 19200 - ap.MagnetictrengthY = float64(bigEndianToInt32(data[495:499])) * 19200 - ap.MagnetictrengthZ = float64(bigEndianToInt32(data[499:503])) * 19200 + ap.MagnetictrengthX = float64(bigEndianToInt32(data[491:495])) / 19200 + ap.MagnetictrengthY = float64(bigEndianToInt32(data[495:499])) / 19200 + ap.MagnetictrengthZ = float64(bigEndianToInt32(data[499:503])) / 19200 ap.ASSTimeInt = binary.BigEndian.Uint32(data[503:507]) ap.ASSTimeDec = uint32(data[507])<<16 | uint32(data[508])<<8 | uint32(data[509]) ap.CheckSum = data[511]