diff --git a/src/protocols/helpers/helpers.go b/src/protocols/helpers/helpers.go index 9088600..8ced03d 100644 --- a/src/protocols/helpers/helpers.go +++ b/src/protocols/helpers/helpers.go @@ -1,5 +1,13 @@ package helpers +import ( + "bytes" + "io" + "log" + "os" + "sync" +) + func ShiftWithConstantSize(arr *[]byte, pos int, length int) { for i := 0; i < length-pos; i++ { (*arr)[i] = (*arr)[pos+i] @@ -30,3 +38,33 @@ func MaxIntSlice(v []int) int { } return index } + +func CaptureOutput(f func()) string { + reader, writer, err := os.Pipe() + if err != nil { + panic(err) + } + stdout := os.Stdout + stderr := os.Stderr + defer func() { + os.Stdout = stdout + os.Stderr = stderr + log.SetOutput(os.Stderr) + }() + os.Stdout = writer + os.Stderr = writer + log.SetOutput(writer) + out := make(chan string) + wg := new(sync.WaitGroup) + wg.Add(1) + go func() { + var buf bytes.Buffer + wg.Done() + io.Copy(&buf, reader) + out <- buf.String() + }() + wg.Wait() + f() + writer.Close() + return <-out +} diff --git a/src/protocols/helpers/processor.go b/src/protocols/helpers/processor.go index 0f3abef..ee3f226 100644 --- a/src/protocols/helpers/processor.go +++ b/src/protocols/helpers/processor.go @@ -2,6 +2,8 @@ package helpers import ( "sort" + + "github.com/fatih/color" ) type Manifest struct { @@ -36,8 +38,9 @@ func (e *ProcessingManifest) Start() { e.WaitForClient(nil) } -func (e *ProcessingManifest) Stop() { +func (e *ProcessingManifest) Stop(re string) { e.Progress.Stop() + color.Magenta(re) } func (e *ProcessingManifest) Update() { diff --git a/src/protocols/hrd/processor/composer/composer.go b/src/protocols/hrd/processor/composer/composer.go index b970918..d2ff354 100644 --- a/src/protocols/hrd/processor/composer/composer.go +++ b/src/protocols/hrd/processor/composer/composer.go @@ -30,7 +30,7 @@ func (e Composer) Render(ch parser.List, outputFolder string) string { // Check if required channels exist. if !ch01.HasData || !ch02.HasData || !ch03.HasData { - //fmt.Println("[COM] Can't export component channel. Not all required channels are available.") + fmt.Println("[COM] Can't export component channel. Not all required channels are available.") return "" } diff --git a/src/protocols/hrd/processor/parser/channel.go b/src/protocols/hrd/processor/parser/channel.go index 569078b..df740bf 100644 --- a/src/protocols/hrd/processor/parser/channel.go +++ b/src/protocols/hrd/processor/parser/channel.go @@ -59,6 +59,9 @@ func (e *Channel) SetBounds(first, last int) { func (e *Channel) Process(scft hrd.SpacecraftParameters) { if e.LastSegment-e.FirstSegment > maxFrameCount { + fmt.Println("[SEN] Potentially invalid channel %s was found.\n", e.ChannelName) + fmt.Println(" It's too long for the round earth, trying to correct...") + if (e.LastSegment - e.LastSegment - e.SegmentCount) < maxFrameCount { e.FirstSegment = e.LastSegment - e.SegmentCount } @@ -68,8 +71,11 @@ func (e *Channel) Process(scft hrd.SpacecraftParameters) { } if e.LastSegment-e.FirstSegment > maxFrameCount { + fmt.Println(" Cannot find any valid number, skipping channel.") return } + + fmt.Println(" Found a valid number. Channel can still be damaged.") } if !e.Processed && e.HasData { diff --git a/src/protocols/hrd/processor/processor.go b/src/protocols/hrd/processor/processor.go index a06a463..10de0bc 100644 --- a/src/protocols/hrd/processor/processor.go +++ b/src/protocols/hrd/processor/processor.go @@ -77,35 +77,37 @@ func (e *Worker) Export(outputPath string, wf img.Pipeline) { fmt.Printf("[PRC] Exporting VIIRS science products.\n") e.manifest.Start() - for _, apid := range e.manifest.Parser.Parse() { - ch := e.channels[apid] + re := helpers.CaptureOutput(func() { + for _, apid := range e.manifest.Parser.Parse() { + ch := e.channels[apid] - var buf []byte - if ch.Export(&buf, e.channels, hrd.Spacecrafts[e.scid]) { - w, h := ch.GetDimensions() - outputName, _ := filepath.Abs(fmt.Sprintf("%s/%s", outputPath, ch.FileName)) + var buf []byte + if ch.Export(&buf, e.channels, hrd.Spacecrafts[e.scid]) { + w, h := ch.GetDimensions() + outputName, _ := filepath.Abs(fmt.Sprintf("%s/%s", outputPath, ch.FileName)) - wf.AddException("Invert", ch.Invert) - wf.Target(img.NewGray16(&buf, w, h)).Process().Export(outputName, 100) - wf.ResetExceptions() + wf.AddException("Invert", ch.Invert) + wf.Target(img.NewGray16(&buf, w, h)).Process().Export(outputName, 100) + wf.ResetExceptions() - e.manifest.Parser[apid].FileName(outputName) - } + e.manifest.Parser[apid].FileName(outputName) + } - e.manifest.ParserCompleted(apid) - } + e.manifest.ParserCompleted(apid) + } - for _, code := range e.manifest.Composer.Parse() { - c := composer.Composers[uint16(code)] - outputName := c.Register(wf, hrd.Spacecrafts[e.scid]).Render(e.channels, outputPath) - e.manifest.Composer[code].FileName(outputName) - e.manifest.ComposerCompleted(code) - } + for _, code := range e.manifest.Composer.Parse() { + c := composer.Composers[uint16(code)] + outputName := c.Register(wf, hrd.Spacecrafts[e.scid]).Render(e.channels, outputPath) + e.manifest.Composer[code].FileName(outputName) + e.manifest.ComposerCompleted(code) + } + }) e.channels = make(parser.List) e.ccsds = nil - e.manifest.Stop() + e.manifest.Stop(re) color.Green("[PRC] Done! All products and components were saved.") } diff --git a/src/protocols/lrpt/processor/composer/composer.go b/src/protocols/lrpt/processor/composer/composer.go index 677314a..65647d8 100644 --- a/src/protocols/lrpt/processor/composer/composer.go +++ b/src/protocols/lrpt/processor/composer/composer.go @@ -31,7 +31,7 @@ func (e Composer) Render(ch parser.List, outputFolder string) string { // Check if required channels exist. if !ch01.HasData || !ch02.HasData || !ch03.HasData { - //fmt.Println("[COM] Can't export component channel. Not all required channels are available.") + fmt.Println("[COM] Can't export component channel. Not all required channels are available.") return "" } diff --git a/src/protocols/lrpt/processor/parser/channel.go b/src/protocols/lrpt/processor/parser/channel.go index a8ad127..ec85339 100644 --- a/src/protocols/lrpt/processor/parser/channel.go +++ b/src/protocols/lrpt/processor/parser/channel.go @@ -95,6 +95,10 @@ func (e *Channel) Process(scft lrpt.SpacecraftParameters) { e.FileName = fmt.Sprintf("%s_%s_BISMW_%s_%d", scft.Filename, scft.SignalName, e.ChannelName, e.StartTime.GetMilliseconds()) e.Height = ((e.LastSegment - e.FirstSegment) / 14) * 8 e.Width = e.FinalWidth + + if e.Height*e.Width < 100 { + e.HasData = false + } } // Parse the current Space Packet Frame into each LRPT protocol channel structure. @@ -113,9 +117,6 @@ func (e *Channel) Parse(packet frames.SpacePacketFrame) { if mcuNumber == 0 && e.offset == 0 { e.offset = (sequence + e.rollover) % 43 % 14 - if e.offset > 10 { - e.offset = 13 - e.offset - } } id := ((sequence + e.rollover - e.offset) / 43 * 14) + mcuNumber diff --git a/src/protocols/lrpt/processor/parser/exporter.go b/src/protocols/lrpt/processor/parser/exporter.go index 9796492..430f8e6 100644 --- a/src/protocols/lrpt/processor/parser/exporter.go +++ b/src/protocols/lrpt/processor/parser/exporter.go @@ -7,11 +7,12 @@ import ( // Export the assets data inside the current LRPT channel. // Data allocation with the current bounds occurs inside this function. func (e *Channel) Export(buf *[]byte, scft lrpt.SpacecraftParameters) bool { + e.Process(scft) + if !e.HasData { return false } - e.Process(scft) *buf = make([]byte, e.Height*e.Width) index := 0 diff --git a/src/protocols/lrpt/processor/processor.go b/src/protocols/lrpt/processor/processor.go index 9906034..eb213d0 100644 --- a/src/protocols/lrpt/processor/processor.go +++ b/src/protocols/lrpt/processor/processor.go @@ -77,35 +77,41 @@ func (e *Worker) Export(outputPath string, wf img.Pipeline) { fmt.Printf("[PRC] Exporting BISMW science products.\n") e.manifest.Start() - for _, apid := range e.manifest.Parser.Parse() { - ch := e.channels[apid] + re := helpers.CaptureOutput(func() { + for _, apid := range e.manifest.Parser.Parse() { + ch := e.channels[apid] - var buf []byte - if ch.Export(&buf, lrpt.Spacecrafts[e.scid]) { - w, h := ch.GetDimensions() - outputName, _ := filepath.Abs(fmt.Sprintf("%s/%s", outputPath, ch.FileName)) + if !ch.HasData { + continue + } - wf.AddException("Invert", ch.Invert) - wf.Target(img.NewGray(&buf, w, h)).Process().Export(outputName, 100) - wf.ResetExceptions() + var buf []byte + if ch.Export(&buf, lrpt.Spacecrafts[e.scid]) { + w, h := ch.GetDimensions() + outputName, _ := filepath.Abs(fmt.Sprintf("%s/%s", outputPath, ch.FileName)) - e.manifest.Parser[apid].FileName(outputName) - } + wf.AddException("Invert", ch.Invert) + wf.Target(img.NewGray(&buf, w, h)).Process().Export(outputName, 100) + wf.ResetExceptions() - e.manifest.ParserCompleted(apid) - } + e.manifest.Parser[apid].FileName(outputName) + } - for _, code := range e.manifest.Composer.Parse() { - c := composer.Composers[code] - outputName := c.Register(wf, lrpt.Spacecrafts[e.scid]).Render(e.channels, outputPath) - e.manifest.Composer[code].FileName(outputName) - e.manifest.ComposerCompleted(code) - } + e.manifest.ParserCompleted(apid) + } + + for _, code := range e.manifest.Composer.Parse() { + c := composer.Composers[code] + outputName := c.Register(wf, lrpt.Spacecrafts[e.scid]).Render(e.channels, outputPath) + e.manifest.Composer[code].FileName(outputName) + e.manifest.ComposerCompleted(code) + } + }) e.channels = make(parser.List) e.ccsds = nil - e.manifest.Stop() + e.manifest.Stop(re) color.Green("[PRC] Done! All products and components were saved.") }