44
44
from xarray import DataTree
45
45
from xarray .backends .common import AbstractDataStore , BackendArray , BackendEntrypoint
46
46
from xarray .backends .file_manager import CachingFileManager
47
+ from xarray .backends .locks import SerializableLock , ensure_lock
47
48
from xarray .backends .store import StoreBackendEntrypoint
48
49
from xarray .core import indexing
49
50
from xarray .core .utils import FrozenDict , close_on_error
78
79
string_dict ,
79
80
)
80
81
82
+ NEXRADL2_LOCK = SerializableLock ()
83
+
84
+
81
85
#: mapping from NEXRAD names to CfRadial2/ODIM
82
86
nexrad_mapping = {
83
87
"REF" : "DBZH" ,
@@ -1324,36 +1328,32 @@ def __init__(self, datastore, name, var):
1324
1328
self .shape = (nrays , nbins )
1325
1329
1326
1330
def _getitem (self , key ):
1327
- # read the data if not available
1328
- try :
1329
- data = self .datastore .ds ["sweep_data" ][self .name ]["data" ]
1330
- print ("ZZZZZAA:" , self .name , data , key )
1331
- except KeyError :
1332
- print ("XXXXX:" , self .group , self .name )
1333
- self .datastore .root .get_data (self .group , self .name )
1334
- data = self .datastore .ds ["sweep_data" ][self .name ]["data" ]
1335
- print ("ZZZZZBB:" , self .name , data , key )
1336
- print ("YY0:" , self .name , len (data ), len (data [0 ]))
1337
- # see 3.2.4.17.6 Table XVII-I Data Moment Characteristics and Conversion for Data Names
1338
- word_size = self .datastore .ds ["sweep_data" ][self .name ]["word_size" ]
1339
- if self .name == "PHI" and word_size == 16 :
1340
- # 10 bit mask, but only for 2 byte data
1341
- x = np .uint16 (0x3FF )
1342
- elif self .name == "ZDR" and word_size == 16 :
1343
- # 11 bit mask, but only for 2 byte data
1344
- x = np .uint16 (0x7FF )
1345
- else :
1346
- x = np .uint8 (0xFF )
1347
- print ("YY1:" , self .name , len (data [0 ]), self .shape )
1348
- if len (data [0 ]) < self .shape [1 ]:
1349
- return np .pad (
1350
- np .vstack (data ) & x ,
1351
- ((0 , 0 ), (0 , self .shape [1 ] - len (data [0 ]))),
1352
- mode = "constant" ,
1353
- constant_values = 0 ,
1354
- )[key ]
1355
- else :
1356
- return (np .vstack (data ) & x )[key ]
1331
+ with self .datastore .lock :
1332
+ # read the data if not available
1333
+ try :
1334
+ data = self .datastore .ds ["sweep_data" ][self .name ]["data" ]
1335
+ except KeyError :
1336
+ self .datastore .root .get_data (self .group , self .name )
1337
+ data = self .datastore .ds ["sweep_data" ][self .name ]["data" ]
1338
+ # see 3.2.4.17.6 Table XVII-I Data Moment Characteristics and Conversion for Data Names
1339
+ word_size = self .datastore .ds ["sweep_data" ][self .name ]["word_size" ]
1340
+ if self .name == "PHI" and word_size == 16 :
1341
+ # 10 bit mask, but only for 2 byte data
1342
+ x = np .uint16 (0x3FF )
1343
+ elif self .name == "ZDR" and word_size == 16 :
1344
+ # 11 bit mask, but only for 2 byte data
1345
+ x = np .uint16 (0x7FF )
1346
+ else :
1347
+ x = np .uint8 (0xFF )
1348
+ if len (data [0 ]) < self .shape [1 ]:
1349
+ return np .pad (
1350
+ np .vstack (data ) & x ,
1351
+ ((0 , 0 ), (0 , self .shape [1 ] - len (data [0 ]))),
1352
+ mode = "constant" ,
1353
+ constant_values = 0 ,
1354
+ )[key ]
1355
+ else :
1356
+ return (np .vstack (data ) & x )[key ]
1357
1357
1358
1358
def __getitem__ (self , key ):
1359
1359
return indexing .explicit_indexing_adapter (
@@ -1365,24 +1365,29 @@ def __getitem__(self, key):
1365
1365
1366
1366
1367
1367
class NexradLevel2Store (AbstractDataStore ):
1368
- def __init__ (self , manager , group = None ):
1368
+ def __init__ (self , manager , group = None , lock = NEXRADL2_LOCK ):
1369
1369
self ._manager = manager
1370
1370
self ._group = int (group [6 :])
1371
1371
self ._filename = self .filename
1372
+ self .lock = ensure_lock (lock )
1372
1373
1373
1374
@classmethod
1374
- def open (cls , filename , mode = "r" , group = None , ** kwargs ):
1375
+ def open (cls , filename , mode = "r" , group = None , lock = None , ** kwargs ):
1376
+ if lock is None :
1377
+ lock = NEXRADL2_LOCK
1375
1378
manager = CachingFileManager (
1376
1379
NEXRADLevel2File , filename , mode = mode , kwargs = kwargs
1377
1380
)
1378
- return cls (manager , group = group )
1381
+ return cls (manager , group = group , lock = lock )
1379
1382
1380
1383
@classmethod
1381
- def open_groups (cls , filename , groups , mode = "r" , ** kwargs ):
1384
+ def open_groups (cls , filename , groups , mode = "r" , lock = None , ** kwargs ):
1385
+ if lock is None :
1386
+ lock = NEXRADL2_LOCK
1382
1387
manager = CachingFileManager (
1383
1388
NEXRADLevel2File , filename , mode = mode , kwargs = kwargs
1384
1389
)
1385
- return {group : cls (manager , group = group ) for group in groups }
1390
+ return {group : cls (manager , group = group , lock = lock ) for group in groups }
1386
1391
1387
1392
@property
1388
1393
def filename (self ):
@@ -1534,6 +1539,7 @@ def open_dataset(
1534
1539
use_cftime = None ,
1535
1540
decode_timedelta = None ,
1536
1541
group = None ,
1542
+ lock = None ,
1537
1543
first_dim = "auto" ,
1538
1544
reindex_angle = False ,
1539
1545
fix_second_angle = False ,
@@ -1543,6 +1549,7 @@ def open_dataset(
1543
1549
store = NexradLevel2Store .open (
1544
1550
filename_or_obj ,
1545
1551
group = group ,
1552
+ lock = lock ,
1546
1553
loaddata = False ,
1547
1554
)
1548
1555
@@ -1610,6 +1617,7 @@ def open_nexradlevel2_datatree(
1610
1617
fix_second_angle = False ,
1611
1618
site_coords = True ,
1612
1619
optional = True ,
1620
+ lock = None ,
1613
1621
** kwargs ,
1614
1622
):
1615
1623
"""Open a NEXRAD Level2 dataset as an `xarray.DataTree`.
@@ -1732,6 +1740,7 @@ def open_nexradlevel2_datatree(
1732
1740
fix_second_angle = fix_second_angle ,
1733
1741
site_coords = site_coords ,
1734
1742
optional = optional ,
1743
+ lock = lock ,
1735
1744
** kwargs ,
1736
1745
)
1737
1746
ls_ds : list [xr .Dataset ] = [sweep_dict [sweep ] for sweep in sweep_dict .keys ()]
@@ -1771,10 +1780,12 @@ def open_sweeps_as_dict(
1771
1780
fix_second_angle = False ,
1772
1781
site_coords = True ,
1773
1782
optional = True ,
1783
+ lock = None ,
1774
1784
** kwargs ,
1775
1785
):
1776
1786
stores = NexradLevel2Store .open_groups (
1777
1787
filename = filename_or_obj ,
1788
+ lock = lock ,
1778
1789
groups = sweeps ,
1779
1790
)
1780
1791
groups_dict = {}
0 commit comments