2

I wrote these two functions in a module when I want to read the band in NetCDF or HDF files and return the band outside the function. Each HDF and NetCDF has many subdatasets. Each subdataset in a NetCDF file has 365 bands while HDF subdataset has only one band. When I run readFile1, there is no problem. However, when I run readFile2 and return the band, I type out.GetNoDataValue() (or other functions attached to it) on the interpreter or in another function, python crashes. In readFile1 function, out.GetNoDataValue() return no data value of the band successfully. When you return the band like in readFile2, you can not do anything with it. When you do, python crashes.

my gdal version is '1100000' (gdal.VersionInfo()) My operating system us ubuntu 12.04 LTS

I think this could be a bug in gdal, I am not sure about it.

from osgeo import gdal
def readFile1(inputFile,variableNo,bandNo):
 filereadtemp=gdal.Open(inputFile)
 fileread=gdal.Open(filereadtemp.GetSubDatasets()[variableNo][0])
 out=fileread.GetRasterBand(bandNo)
 nodatavalue=out.GetNoDataValue()
 return nodatavalue
def readFile2(inputFile,variableNo,bandNo):
 filereadtemp=gdal.Open(inputFile)
 fileread=gdal.Open(filereadtemp.GetSubDatasets()[variableNo][0])
 out=fileread.GetRasterBand(bandNo)
 return out
PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
asked Aug 8, 2015 at 2:09

1 Answer 1

5

The dataset is getting dereferenced when you return only the band from your function.

The solution is to return the dataset from your function.

From the GDAL Python Gotchas page:

Python crashes if you use an object after deleting an object it has a relationship with

Consider this example:

from osgeo import gdal
dataset = gdal.Open('C:\\RandomData.img')
band = dataset.GetRasterBand(1)
print band.Checksum()
31212

In this example, band has a relationship with dataset that requires dataset to remain allocated in order for band to work. If we delete dataset and then try to use band, Python will crash:

from osgeo import gdal
dataset = gdal.Open('C:\\RandomData.img')
band = dataset.GetRasterBand(1)
del dataset # This will cause the Python garbage collector to deallocate dataset
band.GetChecksum() # This will now crash Python because the band's dataset is gone
< Python crashes >

This problem can manifest itself in subtle ways. For example, can occur if you try to instantiate a temporary dataset instance within a single line of code:

from osgeo import gdal
print gdal.Open('C:\\RandomData.img').GetRasterBand(1).Checksum()
< Python crashes >

In this example, the dataset instance was no longer needed after the call to GetRasterBand() so Python deallocated it before calling Checksum().

This problem occurs because the GDAL and OGR objects are implemented in C++ and the relationships between them are maintained in C++ using pointers. When you delete the dataset instance in Python it causes the C++ object behind it to be deallocated. But the C++ object behind the band instance does not know that this happened, so it contains a pointer to the C++ dataset object that no longer exists. When the band tries to access the non-existing object, the process crashes.

The GDAL team knows that this design is not what Python programmers expect. Unfortunately the design is difficult to correct so it is likely to remain for some time.

answered Aug 8, 2015 at 5:12
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.