import
argparse
import
sys
import
os
import
rpreddtypes
import
numpy as np
import
re
import
datetime
import
math
phantomRainRadius
=
20
phantomRainFrac
=
0.5
epoch
=
datetime.datetime(year
=
2015
, month
=
1
, day
=
1
,
hour
=
0
, minute
=
0
)
def
rotate_pixel_CCW (pixel, centre, nDiv, rotNum):
if
nDiv
=
=
1
:
return
pixel.copy()
if
nDiv <
=
0
or
rotNum <
=
0
or
rotNum > nDiv:
print
(
'Invalid invocation of rotate_pixel_CCW. '
'nDiv={0} and rotNum={1}'
.
format
(nDiv, rotNum))
sys.exit(
1
)
delta
=
pixel.copy()
delta[
0
]
-
=
centre[
0
]
delta[
1
]
-
=
centre[
1
]
rval
=
pixel.copy()
if
nDiv
=
=
2
or
( nDiv
=
=
4
and
rotNum
=
=
2
):
rval[
0
]
=
centre[
0
]
-
delta[
0
]
rval[
1
]
=
centre[
1
]
-
delta[
1
]
return
rval
if
nDiv
=
=
4
:
if
rotNum
=
=
1
:
rval[
0
]
=
centre[
0
]
+
delta[
1
]
rval[
1
]
=
centre[
1
]
-
delta[
0
]
return
rval
if
rotNum
=
=
3
:
rval[
0
]
=
centre[
0
]
-
delta[
1
]
rval[
1
]
=
centre[
1
]
+
delta[
0
]
return
rval
theta
=
(np.pi
*
2
/
nDiv)
*
rotNum
sinT
=
np.sin(theta)
cosT
=
np.cos(theta)
rmat
=
np.array(((c, s), (
-
s, c)))
deltavec
=
np.array(delta)
deltavec
=
rmat.dot(deltavec)
rval[
0
]
=
centre[
0
]
+
deltavec[
0
]
rval[
1
]
=
centre[
1
]
+
deltavec[
1
]
return
rval
def
computeSequenceNumber(filename):
match
=
re.search(r
'.*([0-9]{4})_([0-9]{2})_([0-9]{2})'
'_([0-9]{2})_([0-9]{2}).*'
, filename)
if
not
match:
return
-
1
year
=
int
(match.group(
1
))
month
=
int
(match.group(
2
))
day
=
int
(match.group(
3
))
hour
=
int
(match.group(
4
))
minute
=
int
(match.group(
5
))
mytime
=
datetime.datetime(year
=
year, month
=
month, day
=
day,
hour
=
hour, minute
=
minute)
delta
=
mytime
-
epoch
return
int
(delta.total_seconds()
/
600
)
def
rainPresent(binReader, centre, sensitivePixels, heavyVal):
maxSeen
=
0
anyRain
=
0
heavyRain
=
0
checkPhantom
=
True
xoffset
=
binReader.xoffset
yoffset
=
binReader.yoffset
offset
=
[xoffset, yoffset]
dataWidth
=
binReader.width
dataHeight
=
binReader.height
data
=
binReader.getNumpyArray()
for
pixel
in
sensitivePixels:
pval
=
data[pixel[
0
]
-
xoffset][pixel[
1
]
-
yoffset]
if
pval >
0
:
anyRain
=
1
if
pval >
1
:
checkPhantom
=
False
if
pval >
=
maxSeen:
maxSeen
=
pval
if
maxSeen >
=
heavyVal:
heavyRain
=
1
return
[
1
,
1
]
if
not
anyRain:
return
[
0
,
0
]
if
not
checkPhantom:
return
[ anyRain, heavyRain ]
nPixels
=
0
nSetPixels
=
0
for
probeY
in
range
(
-
phantomRainRadius, phantomRainRadius):
deltaX
=
int
(math.sqrt(phantomRainRadius
*
*
2
-
probeY
*
*
2
))
for
probeX
in
range
(
-
deltaX, deltaX):
probePt
=
[ centre[
0
]
+
probeX
-
offset[
0
],
centre[
1
]
+
probeY
-
offset[
1
]]
if
( probePt[
0
] <
0
or
probePt[
0
] >
=
dataWidth
or
probePt[
1
] <
0
or
probePt[
1
] >
=
dataHeight ):
continue
nPixels
+
=
1
pixelVal
=
data[probePt[
0
]][probePt[
1
]]
if
pixelVal >
1
:
return
[anyRain, heavyRain]
if
pixelVal
=
=
1
:
nSetPixels
+
=
1
if
nSetPixels >
=
nPixels
*
phantomRainFrac:
return
[ anyRain, heavyRain ]
else
:
return
[
0
,
0
]
parser
=
argparse.ArgumentParser(description
=
'Build training sequence.'
,
formatter_class
=
argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
'ifilenames'
,
type
=
str
, metavar
=
'filename'
,
nargs
=
'+'
,
help
=
'Filenames to process'
)
parser.add_argument(
'--override-centre'
,
type
=
list
, dest
=
'centre'
,
default
=
[
240
,
239
],
help
=
'Set a new location for '
'the pixel coordinates of the radar station'
)
parser.add_argument(
'--override-sensitive-region'
,
type
=
list
,
dest
=
'sensitive'
,
default
=
[[
264
,
204
], [
264
,
205
], [
265
,
204
], [
265
,
205
]],
help
=
'Set a new list of sensitive pixels'
)
parser.add_argument(
'--rotations'
,
type
=
int
, dest
=
'rotations'
,
default
=
0
,
help
=
'Number of synthetic data points '
'to create (via rotation) for each input data point'
)
parser.add_argument(
'--heavy-rain-index'
,
type
=
int
, dest
=
'heavy'
,
default
=
3
,
help
=
'Lowest index in the colour table '
'that indicates heavy rain, where 1 is the '
'lightest rain.'
)
args
=
parser.parse_args()
hashString
=
rpreddtypes.genhash(args.centre, args.sensitive, args.heavy)
for
inputfile
in
args.ifilenames:
rpReader
=
rpreddtypes.RpBinReader()
rpReader.read(inputfile)
record
=
'{0} {1} {2} {3}'
.
format
(computeSequenceNumber(inputfile),
os.path.abspath(inputfile),
rpreddtypes.genhash(args.centre,
args.sensitive,
args.heavy),
args.rotations)
truevals
=
rainPresent(rpReader, args.centre, args.sensitive, args.heavy)
record
=
'{0} {1} {2}'
.
format
(record, truevals[
0
], truevals[
1
])
for
rot
in
range
(args.rotations):
sense2
=
args.sensitive.copy()
for
i
in
range
(
len
(sense2)):
sense2[i]
=
rotate_pixel_CCW(sense2[i], args.centre,
args.rotations
+
1
, rot
+
1
)
truevals
=
rainPresent(rpReader, args.centre, sense2, args.heavy)
record
=
'{0} {1} {2}'
.
format
(record, truevals[
0
], truevals[
1
])
print
(record)