sen2cor seems fundamentally broken at a resolution of 10 m, but there is a workaround:
Background Information
When started as L2A_Process --resolution 10 sen2cor_L1C_test
the process performs the preliminary calculations for resolution 60 m and resolution 20 m and then crashes with a DistutilsFileError
, because it could not copy a file over another file that was still in use.
The obvious error is the DistutilsFileError
: the _copy_file_contents()
method in file_util.py
checks if the copy destination is an existing file, and if so, it attempts to delete that file first (according to the docs, you can silently overwrite an existing file under Linux, while this results in an error under Windows). That delete operation fails if the target is still in use – which is the case if you try to copy a file to itself.
I didn’t delve into the code to find out why the L2A_Process wants to copy a file to itself (the root error), but a basic workaround is to skip the copy operation if source and destination are one and the same file:
Workaround
In file L2A_Tables.py
at lines 1380++, replace
def postprocess(self): dummy, basename = os.path.split(self.config.L2A_TILE_MTD_XML) fnAux = basename.replace('_MTD_', '_GIP_') # copy configuration to AUX dir: target = os.path.join(self._L2A_AuxDataDir,fnAux) copy_file(self.config.configFn, target) return
with
def postprocess(self): dummy, basename = os.path.split(self.config.L2A_TILE_MTD_XML) fnAux = basename.replace('_MTD_', '_GIP_') # copy configuration to AUX dir: target = os.path.join(self._L2A_AuxDataDir,fnAux)
# begin new stuff (CSe, 2016-01-25) if( os.path.normpath( target ) == os.path.normpath( self.config.configFn ) ): sys.stdout.write('Skipped auto-referential copy of "' + target + '"\n') return if( os.path.exists(target) ): sys.stdout.write('Trying to copy\n"%s" to\n"%s"\n..., but target already exists!\n' % (self.config.configFn, target)) try: os.unlink(target) except os.error, (errno, errstr): sys.stdout.write('Could not delete blocking target file "%s" before copy operation: %s\n' % (target, errstr)) sys.stdout.write('Please delete the file manually.\n' ) raw_input('\nIs the file deleted? [y/n]: ') # end new stuff (CSe, 2016-01-25)
copy_file(self.config.configFn, target) return
Please note that Python is picky about indentation: make sure that the entire method body is indented four more spaces than the def postprocess(self):
line, that the if()
s are indented as far as the copy_file()
call, that the parts within the if
scopes are indented four more spaces, that the parts in the try
and except
scopes are indented yet another four spaces, and that you are indeed using spaces instead of tabs.
This first checks if copy source and copy destination are identical and if so, it skips the operation. If they are different files it checks if the target already exists, and if so, it tries to delete the file. If that fails, it waits for the user to manually delete the file before performing the actual copy operation – but that’s probably overkill, and I don’t know how it work in the SNAP GUI environment instead of a command line interface …
I can’t promise that I’ll find the time today to create a patch for the GitHub repository; feel free to patch and test it yourselves.