-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreadSnapshot.go
195 lines (174 loc) · 5.01 KB
/
readSnapshot.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
package slt
import (
"bufio"
"fmt"
"log"
"os"
"regexp"
"strings"
"time"
"github.com/brunetto/goutils/debug"
"github.com/brunetto/goutils/readfile"
)
// DumbSnapshot contains one snapshot without knowing anything about it
type DumbSnapshot struct {
Timestep string
Integrity bool
NestingLevel int
MaxNesting int
CheckRoot bool
Lines []string
}
// WriteSnapshot pick the snapshot line by line and write it to the
// output file
func (snap *DumbSnapshot) WriteSnapshot(nWriter *bufio.Writer) (err error) {
if Debug {
defer debug.TimeMe(time.Now())
}
for _, line := range snap.Lines {
_, err = nWriter.WriteString(line + "\n")
// if err = nWriter.Flush(); err != nil {
// log.Fatal(err)
// }
}
if err = nWriter.Flush(); err != nil {
log.Fatal(err)
}
return err
}
// ReadOutSnapshot read one and only one snapshot at a time
func ReadOutSnapshot(nReader *bufio.Reader, checkRoot bool) (*DumbSnapshot, error) {
if Debug {
defer debug.TimeMe(time.Now())
}
var (
snap *DumbSnapshot = new(DumbSnapshot)
line string
err error
regSysTime = regexp.MustCompile(`system_time\s*=\s*(\d+)`)
resSysTime []string
cumulativeNesting int = 0
CheckRoot bool
)
// Init snapshot container
snap.Lines = make([]string, 0)
snap.Integrity = false
snap.CheckRoot = false
snap.NestingLevel = 0
for {
// Read line by line
if line, err = readfile.Readln(nReader); err != nil {
// Mark snapshot as corrupted
snap.Integrity = false
return snap, err
}
// Add line to the snapshots in memory
snap.Lines = append(snap.Lines, line)
// Search for timestep number
if resSysTime = regSysTime.FindStringSubmatch(line); resSysTime != nil {
snap.Timestep = resSysTime[1]
}
// Check if entering or exiting a particle
// and update the nesting level
if strings.Contains(line, "(Particle") {
snap.NestingLevel++
cumulativeNesting++
} else if strings.Contains(line, ")Particle") {
snap.NestingLevel--
}
// Doesn't work with ICs because they are without name = root grrrr
if strings.Contains(line, "name = root") {
snap.CheckRoot = true
}
// Check whether the whole snapshot is in memory
// (root particle complete) and if true, return
// We need cumulative nesting in case of a header.
// Without it the result is always a bad snapshot because
// the nesting is 0 and no root is found but only
// because we are not into the particles section
if snap.NestingLevel == 0 && cumulativeNesting != 0 {
if CheckRoot && !snap.CheckRoot {
outFile, err := os.Create("badTimestep.txt")
defer outFile.Close()
if err != nil {log.Fatal(err)}
nWriter := bufio.NewWriter(outFile)
defer nWriter.Flush()
snap.WriteSnapshot(nWriter)
fmt.Println()
log.Fatal("No root particle in a timestep that seems complete, please check!")
}
snap.Integrity = true
if Verb {
log.Println("Timestep ", snap.Timestep, " integrity set to: ", snap.Integrity)
} else {
fmt.Fprintf(os.Stderr, "\r\tTimestep %v integrity set to: %v", snap.Timestep, snap.Integrity)
}
return snap, err
}
}
}
// ReadErrSnapshot read one and only one snapshot at a time
func ReadErrSnapshot(nReader *bufio.Reader) (*DumbSnapshot, error) {
if Debug {
defer debug.TimeMe(time.Now())
}
var (
snap *DumbSnapshot = new(DumbSnapshot)
line string
err error
regSysTime = regexp.MustCompile(`^Time = (\d+)`)
resSysTime []string
endOfSnap string = "----------------------------------------"
// This variables are the idxs to print the last or last 10 lines
dataStartIdx int = 0
dataEndIdx int
)
// Init snapshot container
snap.Lines = make([]string, 0) //FIXME: check if 0 is ok!!!
snap.Integrity = false
snap.CheckRoot = false
snap.Timestep = "-1"
for {
// Read line by line
if line, err = readfile.Readln(nReader); err != nil {
if err.Error() == "EOF" {
if Verb {
fmt.Println()
log.Println("File reading complete...")
log.Println("Timestep not complete.")
log.Println("Last ten lines:")
dataEndIdx = len(snap.Lines) - 1
// Check that we have more than 10 lines
if dataEndIdx > 10 {
dataStartIdx = dataEndIdx - 10
}
for idx, row := range snap.Lines[dataStartIdx:dataEndIdx] {
fmt.Println(idx, ": ", row)
}
}
} else {
log.Fatal("Non EOF error while reading ", err)
}
// Mark snapshot as corrupted
snap.Integrity = false
return snap, err
}
// Add line to the snapshots in memory
snap.Lines = append(snap.Lines, line)
// Search for timestep number
if resSysTime = regSysTime.FindStringSubmatch(line); resSysTime != nil {
snap.Timestep = resSysTime[1]
}
// Check if entering or exiting a particle
// and update the nesting level
if strings.Contains(line, endOfSnap) {
snap.Integrity = true
if Verb {
log.Println("Timestep ", snap.Timestep, " integrity set to: ", snap.Integrity)
} else {
fmt.Fprintf(os.Stderr, "\r\tTimestep %v integrity set to: %v", snap.Timestep, snap.Integrity)
}
return snap, err
}
}
}