Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Andrew Leonard
kisfido
Commits
92ce4bd9
Commit
92ce4bd9
authored
Nov 05, 2021
by
Derek Homeier
Browse files
Unpack obsrec description into QueryResponseColumns + Units
parent
00357eb4
Pipeline
#2758
passed with stage
in 4 minutes and 3 seconds
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
sdc/client.py
View file @
92ce4bd9
# -*- coding: utf-8 -*-
#
# Authors: Derek Homeier <derek.homeier@aperiosoftware.com>
# Andrew Leonard <drew@aperiosoftware.com>
#
import
os
import
copy
...
...
@@ -261,6 +265,17 @@ class KISClient(BaseClient):
results : `~sunpy.net.base_client.QueryResponseTable`
A `QueryResponseTable` instance containing the query result.
"""
# Unit converters for 'description' fields
converters
=
{
'ATMOS'
:
lambda
x
:
x
*
u
.
cm
,
'DATE_'
:
lambda
x
:
Time
(
x
[
'$date'
]
*
1e-3
,
format
=
'unix'
),
'EXPTI'
:
lambda
x
:
x
*
u
.
s
,
'HPLN_'
:
lambda
x
:
x
*
u
.
arcsec
,
'HPLT_'
:
lambda
x
:
x
*
u
.
arcsec
,
'S_RES'
:
lambda
x
:
x
*
u
.
arcsec
,
'THETA'
:
lambda
x
:
x
*
u
.
deg
,
'T_RES'
:
lambda
x
:
x
*
u
.
deg
,
'WAVEL'
:
lambda
x
:
x
*
u
.
nm
}
query
=
and_
(
*
query
)
# Not very extensively tested on hierarchical queries
...
...
@@ -277,6 +292,10 @@ class KISClient(BaseClient):
obs_dict
=
json
.
loads
(
response
.
read
()).
get
(
'_embedded'
,
[])
if
len
(
obs_dict
)
>
0
and
'links'
in
obs_dict
[
0
]:
l1_data
=
obs_dict
[
0
][
'links'
].
get
(
'l1_data'
,
[])
obs_dict
[
0
].
update
(
obs_dict
[
0
].
pop
(
'description'
,
dict
()))
for
k
in
obs_dict
[
0
].
keys
():
if
k
[:
5
]
in
converters
:
obs_dict
[
0
][
k
]
=
converters
[
k
[:
5
]](
obs_dict
[
0
][
k
])
obs_rec
=
[]
for
exp
in
l1_data
:
obs_rec
.
append
(
copy
.
deepcopy
(
obs_dict
[
0
]))
...
...
@@ -316,11 +335,11 @@ class KISClient(BaseClient):
ext
=
'json'
for
row
in
query_results
:
inst
=
row
[
'
description'
][
'
INSTRUMENT'
]
inst
=
row
[
'INSTRUMENT'
]
oid
=
row
[
'links'
][
'l1_data'
][
'$oid'
]
# Content-Disposition header default is "{row['_id']['$oid']}/{oid}.{ext}" (no '.json').
# rowpath = row['_id']['$oid']
filepath
=
os
.
path
.
join
(
row
[
'
description'
][
'
OBS_NAME'
],
f
"
{
oid
}
.
{
ext
}
"
)
filepath
=
os
.
path
.
join
(
row
[
'OBS_NAME'
],
f
"
{
oid
}
.
{
ext
}
"
)
url
=
f
"
{
self
.
_BASE_URL
}{
inst
}
_l1_data.files/
{
oid
}{
binfile
}
"
downloader
.
enqueue_file
(
url
,
filename
=
str
(
path
).
format
(
file
=
filepath
,
**
row
.
response_block_map
))
...
...
sdc/tests/test_client.py
View file @
92ce4bd9
...
...
@@ -8,6 +8,7 @@ import json
import
parfive
import
astropy.units
as
u
from
astropy
import
table
from
astropy.io
import
fits
from
astropy.time
import
Time
import
sunpy
...
...
@@ -69,13 +70,11 @@ def test_docker(client):
res
=
client
.
search
(
a
.
Instrument
(
"GRIS"
)
&
a
.
sdc
.
ObsName
(
'gris_20140426_000'
))
assert
isinstance
(
res
,
QueryResponseTable
)
assert
len
(
res
)
==
105
description
=
res
[
0
].
get
(
'description'
)
assert
len
(
description
)
==
34
assert
description
[
'INSTRUMENT'
]
==
'gris'
assert
description
[
'TELESCOPE'
]
==
'GREGOR'
assert
description
[
'BTYPE'
]
==
'phot.count'
assert
description
[
'DATE_BEG'
][
'$date'
]
==
1398505619000
assert
description
[
'DATE_END'
][
'$date'
]
==
1398506021300
assert
res
[
0
][
'INSTRUMENT'
]
==
'gris'
assert
res
[
0
][
'TELESCOPE'
]
==
'GREGOR'
assert
res
[
0
][
'BTYPE'
]
==
'phot.count'
assert
res
[
0
][
'DATE_BEG'
].
unix
==
1398505619.000
assert
res
[
0
][
'DATE_END'
].
unix
==
1398506021.300
file_ids
=
[
ld
[
'links'
][
'l1_data'
][
'$oid'
]
for
ld
in
res
]
assert
len
(
file_ids
)
==
105
...
...
@@ -89,7 +88,7 @@ def test_docker(client):
date
=
a
.
Time
(
"2014/04/26 01:00"
,
"2014/04/26 22:00"
)
downloader
=
parfive
.
Downloader
()
inst
=
res
[
0
][
'
description'
][
'
INSTRUMENT'
]
inst
=
res
[
0
][
'INSTRUMENT'
]
rowpath
=
f
"
{
res
[
0
][
'_id'
][
'$oid'
]
}
"
binfile
=
''
ext
=
'json'
...
...
@@ -166,7 +165,7 @@ def test_search(client):
res
=
client
.
search
(
query
)
assert
isinstance
(
res
,
QueryResponseTable
)
assert
len
(
res
)
==
1
assert
'
description
'
in
res
.
colnames
assert
'
INSTRUMENT
'
in
res
.
colnames
else
:
with
pytest
.
raises
(
URLError
,
match
=
rf
"
{
_dockerexc
(
'bbi'
)
}
"
r
"{'description.DATE_BEG':{'.lte':{'.date':'2017-05-22T22:00:00.000'}}},"
...
...
@@ -180,7 +179,7 @@ def test_search(client):
if
HAS_DOCKERTEST
:
res
=
client
.
search
(
query
)
assert
len
(
res
)
==
1
assert
'
description
'
in
res
.
colnames
assert
'
INSTRUMENT
'
in
res
.
colnames
else
:
with
pytest
.
raises
(
URLError
,
match
=
rf
"
{
_dockerexc
(
'lars'
)
}
"
r
"{'description.HPLT_TAN_MIN':{'.lte':12}},"
...
...
@@ -192,7 +191,7 @@ def test_search(client):
if
HAS_DOCKERTEST
:
res
=
client
.
search
(
*
query
)
assert
len
(
res
)
==
1
assert
'
description
'
in
res
.
colnames
assert
'
INSTRUMENT
'
in
res
.
colnames
else
:
with
pytest
.
raises
(
URLError
,
match
=
rf
"
{
_dockerexc
(
'lars'
)
}
"
r
"{'description.HPLT_TAN_MIN':{'.lte':12}},"
...
...
@@ -204,11 +203,9 @@ def test_search(client):
if
HAS_DOCKERTEST
:
res
=
client
.
search
(
query
)
assert
len
(
res
)
==
362
assert
'description'
in
res
.
colnames
assert
'THETA'
in
res
[
0
][
'description'
]
theta
=
[
obs
[
'description'
][
'THETA'
]
for
obs
in
res
]
assert
(
min
(
theta
[:
100
])
>=
50
)
&
(
max
(
theta
[:
100
])
<=
85
)
assert
res
[
100
][
'description'
][
'POL_STATES'
]
==
'IQUV'
assert
'THETA'
in
res
.
colnames
assert
(
min
(
res
[
'THETA'
][:
100
])
>=
50
*
u
.
deg
)
&
(
max
(
res
[
'THETA'
][:
100
])
<=
85
*
u
.
deg
)
assert
res
[
100
][
'POL_STATES'
]
==
'IQUV'
else
:
# Will raise on first of multi-part OR queries; somehow switches INSTRUMENT and THETA.
with
pytest
.
raises
(
URLError
,
match
=
rf
"
{
_dockerexc
(
'gris'
)[:
80
]
}
"
)
as
exc
:
...
...
@@ -220,10 +217,8 @@ def test_search(client):
if
HAS_DOCKERTEST
:
res
=
client
.
search
(
*
query
)
assert
len
(
res
)
==
163
assert
'description'
in
res
.
colnames
assert
'THETA'
in
res
[
0
][
'description'
]
theta
=
[
obs
[
'description'
][
'THETA'
]
for
obs
in
res
]
assert
(
min
(
theta
)
>=
50
)
&
(
max
(
theta
)
<=
85
)
assert
'THETA'
in
res
.
colnames
assert
(
min
(
res
[
'THETA'
])
>=
50
*
u
.
deg
)
&
(
max
(
res
[
'THETA'
])
<=
85
*
u
.
deg
)
else
:
# Will raise on first of multi-part OR queries; somehow switches INSTRUMENT and THETA.
with
pytest
.
raises
(
URLError
,
match
=
rf
"
{
_dockerexc
(
'LARS'
)[:
80
]
}
"
)
as
exc
:
...
...
@@ -238,37 +233,37 @@ def test_fido_search():
if
HAS_DOCKERTEST
:
res
=
Fido
.
search
(
a
.
Instrument
(
"GRIS"
)
&
a
.
sdc
.
Theta
(
50
*
u
.
deg
,
80
*
u
.
deg
))
assert
len
(
res
[
'kis'
])
==
162
theta
=
[
obs
[
'description'
][
'THETA'
]
for
obs
in
res
[
'kis'
]]
assert
(
min
(
theta
)
>=
50
)
&
(
max
(
theta
)
<=
80
)
assert
(
min
(
res
[
'kis'
][
'THETA'
])
>=
50
*
u
.
deg
)
&
(
max
(
res
[
'kis'
][
'THETA'
])
<=
80
*
u
.
deg
)
res
=
Fido
.
search
(
a
.
Instrument
(
"GRIS"
),
a
.
sdc
.
Theta
(
50
*
u
.
deg
,
80
*
u
.
deg
))
assert
len
(
res
[
'kis'
])
==
162
theta
=
[
obs
[
'description'
][
'THETA'
]
for
obs
in
res
[
'kis'
]]
assert
(
min
(
theta
)
>=
50
)
&
(
max
(
theta
)
<=
80
)
assert
(
min
(
res
[
'kis'
][
'THETA'
])
>=
50
*
u
.
deg
)
&
(
max
(
res
[
'kis'
][
'THETA'
])
<=
80
*
u
.
deg
)
date
=
a
.
Time
(
"2017/05/12 01:40"
,
"2017/05/16 19:00"
)
res
=
Fido
.
search
(
a
.
Instrument
(
"LARS"
)
&
date
)
assert
len
(
res
[
'kis'
])
>
0
date_beg
=
[
obs
[
'description'
][
'DATE_BEG'
][
'$date'
]
for
obs
in
res
[
'kis'
]]
date_end
=
[
obs
[
'description'
][
'DATE_END'
][
'$date'
]
for
obs
in
res
[
'kis'
]]
assert
max
(
date_beg
)
<
date
.
end
.
unix
*
1000
assert
min
(
date_end
)
>
date
.
start
.
unix
*
1000
assert
max
(
res
[
'kis'
][
'DATE_BEG'
])
<
date
.
end
assert
min
(
res
[
'kis'
][
'DATE_END'
])
>
date
.
start
res
=
Fido
.
search
(
two_inst
,
a
.
sdc
.
Theta
(
50
*
u
.
deg
,
80
*
u
.
deg
))
assert
len
(
res
[
'kis'
])
==
2
assert
len
(
res
[
'kis'
][
0
])
==
1
assert
len
(
res
[
'kis'
][
1
])
==
162
assert
res
[
'kis'
][
0
][
0
][
'description'
][
'INSTRUMENT'
]
==
'lars'
theta
=
[
obs
[
'description'
][
'THETA'
]
for
obs
in
res
[
'kis'
][
0
]]
assert
(
min
(
theta
)
>=
50
)
&
(
max
(
theta
)
<=
80
)
assert
res
[
'kis'
][
1
,
0
][
'description'
][
'INSTRUMENT'
]
==
'gris'
theta
=
[
obs
[
'description'
][
'THETA'
]
for
obs
in
res
[
'kis'
][
1
]]
assert
(
min
(
theta
)
>=
50
)
&
(
max
(
theta
)
<=
80
)
assert
res
[
'kis'
][
0
][
0
][
'INSTRUMENT'
]
==
'lars'
assert
res
[
'kis'
][
1
,
0
][
'INSTRUMENT'
]
==
'gris'
assert
(
min
(
res
[
'kis'
][
0
][
'THETA'
])
>=
50
*
u
.
deg
)
&
(
max
(
res
[
'kis'
][
0
][
'THETA'
])
<=
80
*
u
.
deg
)
assert
(
min
(
res
[
'kis'
][
1
][
'THETA'
])
>=
50
*
u
.
deg
)
&
(
max
(
res
[
'kis'
][
1
][
'THETA'
])
<=
80
*
u
.
deg
)
theta
=
[
obs
[
'THETA'
]
for
obs
in
res
[
'kis'
][
0
]]
assert
(
min
(
theta
)
>=
50
*
u
.
deg
)
&
(
max
(
theta
)
<=
80
*
u
.
deg
)
theta
=
[
obs
[
'THETA'
]
for
obs
in
res
[
'kis'
][
1
]]
assert
(
min
(
theta
)
>=
50
*
u
.
deg
)
&
(
max
(
theta
)
<=
80
*
u
.
deg
)
date
=
a
.
Time
(
"2016/08/26 16:25"
,
"2016/08/26 16:45"
)
res
=
Fido
.
search
(
a
.
Instrument
(
"GRIS"
),
a
.
sdc
.
PolStates
(
'iquv'
),
date
)
assert
len
(
res
[
'kis'
])
==
400
assert
res
[
'kis'
][
0
][
'description'
][
'POL_STATES'
]
==
'IQUV'
assert
all
(
res
[
'kis'
][
'POL_STATES'
]
==
'IQUV'
)
assert
max
(
res
[
'kis'
][
'DATE_BEG'
])
<
date
.
end
assert
min
(
res
[
'kis'
][
'DATE_END'
])
>
date
.
start
else
:
with
pytest
.
raises
(
URLError
,
match
=
rf
"
{
_dockerexc
(
'gris'
)
}
"
r
"{'description.THETA':{'.gte':50,'.lte':80}}"
):
...
...
@@ -292,25 +287,23 @@ def test_fido_fetch():
date
=
a
.
Time
(
"2017/05/22 08:45"
,
"2017/05/22 08:55"
)
res
=
Fido
.
search
(
a
.
Instrument
(
"BBI"
),
date
)
assert
len
(
res
[
'kis'
])
==
10
desc
=
[
r
[
'description'
]
for
r
in
res
[
'kis'
]]
assert
max
([
d
[
'DATE_BEG'
][
'$date'
]
for
d
in
desc
])
<
date
.
end
.
unix
*
1000
assert
min
([
d
[
'DATE_END'
][
'$date'
]
for
d
in
desc
])
>
date
.
start
.
unix
*
1000
assert
max
(
res
[
'kis'
][
'DATE_BEG'
])
<
date
.
end
assert
min
(
res
[
'kis'
][
'DATE_END'
])
>
date
.
start
files
=
Fido
.
fetch
(
res
[
'kis'
])
assert
len
(
files
)
==
10
for
i
,
filepath
in
enumerate
(
files
):
assert
dirnames
(
filepath
)[
-
1
]
==
d
es
c
[::
-
1
][
i
][
'OBS_NAME'
]
assert
dirnames
(
filepath
)[
-
1
]
==
r
es
[
'kis'
]
[::
-
1
][
i
][
'OBS_NAME'
]
meta
=
json
.
load
(
open
(
filepath
))
assert
meta
[
'_id'
][
'$oid'
]
==
os
.
path
.
splitext
(
os
.
path
.
basename
(
filepath
))[
0
]
assert
date
.
start
.
isot
[:
12
]
in
meta
[
'metadata'
][
'header'
][
'DATE-BEG'
]
assert
date
.
start
<
Time
(
meta
[
'metadata'
][
'header'
][
'DATE-BEG'
])
<
date
.
end
assert
meta
[
'metadata'
][
'header'
][
'FILENAME'
].
split
(
'-'
)[
0
]
in
d
es
c
[::
-
1
][
i
][
'OBS_NAME'
]
assert
meta
[
'metadata'
][
'header'
][
'FILENAME'
].
split
(
'-'
)[
0
]
in
r
es
[
'kis'
][
9
-
i
][
'OBS_NAME'
]
files
=
Fido
.
fetch
(
res
[
'kis'
][:
3
],
binary
=
True
)
assert
len
(
files
)
==
3
for
i
,
filepath
in
enumerate
(
files
):
assert
dirnames
(
filepath
)[
-
1
]
==
d
es
c
[::
-
1
][
i
][
'OBS_NAME'
]
assert
dirnames
(
filepath
)[
-
1
]
==
r
es
[
'kis'
]
[::
-
1
][
i
][
'OBS_NAME'
]
hdulist
=
fits
.
open
(
filepath
)
assert
hdulist
[
0
].
header
.
get
(
'TELESCOP'
)
==
'GREGOR'
assert
hdulist
[
0
].
header
.
get
(
'INSTRUME'
)
==
'BBI'
...
...
@@ -335,9 +328,8 @@ def test_fido_fetch_2():
res
=
Fido
.
search
((
a
.
Instrument
(
"GRIS"
)
|
a
.
Instrument
(
"LARS"
))
&
date
)
assert
len
(
res
[
'kis'
])
==
2
assert
len
(
res
[
'kis'
][
0
])
==
400
assert
res
[
'kis'
][
0
][
0
][
'description'
][
'DATE_BEG'
][
'$date'
]
<
date
.
end
.
unix
*
1000
assert
res
[
'kis'
][
0
][
0
][
'description'
][
'DATE_END'
][
'$date'
]
>
date
.
start
.
unix
*
1000
assert
max
(
res
[
'kis'
][
0
][
'DATE_BEG'
])
<
date
.
end
assert
min
(
res
[
'kis'
][
0
][
'DATE_END'
])
>
date
.
start
files
=
Fido
.
fetch
(
res
[
'kis'
][
0
,
:
100
],
binary
=
False
)
assert
len
(
files
)
==
100
...
...
@@ -372,19 +364,18 @@ def test_fido_fetch_2():
assert
len
(
res
[
'kis'
])
==
2
assert
len
(
res
[
'kis'
][
0
])
==
300
assert
len
(
res
[
'kis'
][
1
])
==
1
desc
=
[
r
[
'description'
]
for
r
in
res
[
'kis'
][
0
]]
+
[
r
[
'description'
]
for
r
in
res
[
'kis'
][
1
]]
dirs
=
[
d
[
'OBS_NAME'
]
for
d
in
desc
]
assert
len
(
desc
)
==
301
assert
max
([
d
[
'DATE_BEG'
][
'$date'
]
for
d
in
desc
])
<
date
.
end
.
unix
*
1000
assert
min
([
d
[
'DATE_END'
][
'$date'
]
for
d
in
desc
])
>
date
.
start
.
unix
*
1000
desc
=
table
.
vstack
(
res
[
'kis'
])
assert
len
(
desc
)
==
301
assert
max
(
desc
[
'DATE_BEG'
])
<
date
.
end
assert
min
(
desc
[
'DATE_END'
])
>
date
.
start
files
=
Fido
.
fetch
(
res
[
'kis'
][:,
:
100
],
binary
=
False
)
assert
len
(
files
.
errors
)
==
0
assert
len
(
files
)
==
101
assert
files
[
0
].
endswith
(
'.json'
)
for
filepath
in
files
:
assert
dirnames
(
filepath
)[
-
1
]
in
d
irs
assert
dirnames
(
filepath
)[
-
1
]
in
d
esc
[
'OBS_NAME'
]
meta
=
json
.
load
(
open
(
filepath
))
assert
meta
[
'_id'
][
'$oid'
]
==
os
.
path
.
splitext
(
os
.
path
.
basename
(
filepath
))[
0
]
assert
date
.
start
.
iso
[:
10
]
in
meta
[
'metadata'
][
'header'
][
'DATE-OBS'
]
...
...
@@ -440,7 +431,7 @@ def test_all_queries(client, query):
if
HAS_DOCKERTEST
:
res
=
client
.
search
(
a
.
Instrument
(
"GRIS"
)
&
query
)
if
len
(
res
)
>
0
:
assert
'description'
in
res
.
colnames
assert
res
[
0
][
'INSTRUMENT'
]
==
'gris'
else
:
with
pytest
.
raises
(
URLError
,
match
=
rf
"
{
_dockerexc
(
'gris'
)
}
"
rf
"{{'description.*
{
query
.
type_name
.
upper
()
}
"
):
...
...
@@ -456,10 +447,8 @@ def test_range(client):
assert
client
.
_can_handle_query
(
query
)
if
HAS_DOCKERTEST
:
res
=
client
.
search
(
query
)
wave_min
=
[
obs
[
'WAVELENGTH_MIN'
]
for
obs
in
res
[
'description'
]]
wave_max
=
[
obs
[
'WAVELENGTH_MAX'
]
for
obs
in
res
[
'description'
]]
assert
max
(
wave_min
)
<=
1250
assert
min
(
wave_max
)
>=
1080
assert
max
(
res
[
'WAVELENGTH_MIN'
])
<=
1250
*
u
.
nm
assert
min
(
res
[
'WAVELENGTH_MAX'
])
>=
1080
*
u
.
nm
else
:
with
pytest
.
raises
(
URLError
,
match
=
rf
"
{
_dockerexc
(
'gris'
)
}
"
r
"{'description.WAVELENGTH_MIN':{'.lte':1250}},"
...
...
@@ -479,7 +468,7 @@ def test_full_range(client):
if
HAS_DOCKERTEST
:
res
=
client
.
search
(
query
)
assert
len
(
res
)
==
105
assert
'
description
'
in
res
.
colnames
assert
'
INSTRUMENT
'
in
res
.
colnames
else
:
with
pytest
.
raises
(
URLError
,
match
=
rf
"
{
_dockerexc
(
'GRIS'
)
}
"
r
"{'description.DATE_BEG':{'.lte':{'.date':'2014-04-26T09:50:00.000'}}},"
...
...
@@ -491,10 +480,8 @@ def test_full_range(client):
query
=
a
.
Instrument
(
"LARS"
)
&
hplt
if
HAS_DOCKERTEST
:
res
=
client
.
search
(
query
)
hplt_tan_min
=
[
obs
[
'HPLT_TAN_MIN'
]
for
obs
in
res
[
'description'
]]
hplt_tan_max
=
[
obs
[
'HPLT_TAN_MAX'
]
for
obs
in
res
[
'description'
]]
assert
max
(
hplt_tan_min
)
<=
6
assert
min
(
hplt_tan_max
)
>=
-
2
assert
max
(
res
[
'HPLT_TAN_MIN'
])
<=
6
*
u
.
arcsec
assert
min
(
res
[
'HPLT_TAN_MAX'
])
>=
-
2
*
u
.
arcsec
else
:
with
pytest
.
raises
(
URLError
,
match
=
rf
"
{
_dockerexc
(
'LARS'
)
}
"
r
"{'description.HPLT_TAN_MIN':{'.lte':6}},"
...
...
@@ -506,10 +493,8 @@ def test_full_range(client):
assert
client
.
_can_handle_query
(
query
)
if
HAS_DOCKERTEST
:
res
=
client
.
search
(
query
)
hplt_tan_min
=
[
obs
[
'HPLT_TAN_MIN'
]
for
obs
in
res
[
'description'
]]
hplt_tan_max
=
[
obs
[
'HPLT_TAN_MAX'
]
for
obs
in
res
[
'description'
]]
assert
max
(
hplt_tan_min
)
<=
-
2
assert
min
(
hplt_tan_max
)
>=
6
assert
max
(
res
[
'HPLT_TAN_MIN'
])
<=
-
2
*
u
.
arcsec
assert
min
(
res
[
'HPLT_TAN_MAX'
])
>=
6
*
u
.
arcsec
else
:
with
pytest
.
raises
(
URLError
,
match
=
rf
"
{
_dockerexc
(
'LARS'
)
}
"
r
"{'description.HPLT_TAN_MIN':{'.lte':-2}},"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment