In SNAP (GUI) I can easily right-click a virtual band and choose ”Convert band” in order to make it a “real band”. I ‘ve been searching the forum and the documentation but can’t find out how to make the same thing using snappy.
Hi Niklas,
Sorry there is no function directly available right now.
Here is the Java code that accomplishes your task in the SNAP Desktop app: ConvertComputedBandIntoBandAction.java.
We will make the conversion code available from a single function in SNAP v5: SNAP-625.
For time being you’ll have to convert the Java code to Python yourself. The important bit is the last line, which copies the source image of the computedBand
into the realBand
. I’m happy to further assist you, if you encounter problems!
Cheers
Norman
Thank you @forman
Then I was on the right track. In snappy I tried to use the VirtualBand.createSourceImage() http://step.esa.int/docs/v4.0/apidoc/engine/org/esa/snap/core/datamodel/VirtualBand.html#createSourceImage--
What I really wanted to do was to “Replace NaN and infinity results by -1”. My approach was to use band math and the expression isnan('bandName')? -1 : 'bandName'
. When doing that I ended up with a virtual band.
//Niklas
I am running SNAP v5, but
snappy.ProductUtils.convertComputedBandToBand
returns
AttributeErrorTraceback (most recent call last)
<ipython-input-48-2edb9646de3f> in <module>()
----> 1 snappy.ProductUtils.convertComputedBandToBand
AttributeError: type object 'org.esa.snap.core.util.ProductUtils' has no attribute 'convertComputedBandToBand'
Unfortunately the issue was wrongly marked as closed. This method is not available in version 5.
It will come with the next release.
for anyone needing this now, here’s what I came up with…
import snappy
snappy.GPF.getDefaultInstance().getOperatorSpiRegistry().loadOperatorSpis()
def convertComputedBandToBand(computedBand):
realBand = snappy.Band(
computedBand.getName(),
computedBand.getDataType(),
computedBand.getRasterWidth(),
computedBand.getRasterHeight()
)
realBand.setDescription(computedBand.getDescription())
realBand.setValidPixelExpression(computedBand.getValidPixelExpression())
realBand.setUnit(computedBand.getUnit())
realBand.setSpectralWavelength(computedBand.getSpectralWavelength())
realBand.setGeophysicalNoDataValue(computedBand.getGeophysicalNoDataValue())
realBand.setNoDataValueUsed(computedBand.isNoDataValueUsed())
if (computedBand.isStxSet()):
realBand.setStx(computedBand.getStx())
imageInfo = computedBand.getImageInfo()
if (imageInfo != None):
realBand.setImageInfo(imageInfo.clone())
product = computedBand.getProduct()
# "Check if all the frame with the raster data are close"
# missing some stuff with topComponent
bandGroup = product.getBandGroup()
bandIndex = bandGroup.indexOf(computedBand)
bandGroup.remove(computedBand)
bandGroup.add(bandIndex, realBand)
realBand.setSourceImage(createSourceImage(computedBand, realBand))
def createSourceImage(computedBand, realBand):
try:
# assume computedBand is actually just a normal band
return computedBand.getSourceImage()
except RuntimeError as e:
if e.message.startswith("java.lang.IllegalArgumentException"):
# now assume computedBand is virtualBand
virtualBand = snappy.jpy.cast(computedBand, snappy.VirtualBand)
return snappy.VirtualBand.createSourceImage(realBand, virtualBand.getExpression())
else:
raise
Unfortunately not, It din’ make it into the release.
You still need to use use the method provided by @oak .