Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

# -*- coding: utf-8 -*- 

# Filename: projectionmixin.py 

""" 

Helper mixin to support projection products 

=========================================== 

 

This is part of the macsProcessor suite. 

 

Copyright (C) 2014 Tobias Kölling 

 

""" 

 

from runmacs.processor.product import Product, ProductMixin 

from runmacs.processor.utils import defaultPartDescriptions 

from runmacs.processor.sugar import * 

import numpy as np 

 

class ProjectionMixin(ProductMixin): 

productType = 'projected_image' 

_requireIndices = ('productType', 'data_type', 'sensorId', 'validFrom', 'validUntil') 

 

productDimensions = {'radiance': ('x', 'y', 'spectral'), 

'previewdata': ('x', 'y', 'color'), 

'forwardmap': ('xy', 'sourcepixels'), 

'reversemap': ('x', 'y'), 

'grid': ('xy', 'x', 'y'), 

'wavelength': ('spectral',),} 

# TODO: this should be individual for different projections 

partDescription = {'radiance': defaultPartDescriptions['radianceData'], 

'previewdata': defaultPartDescriptions['previewdata'], 

'forwardmap': defaultPartDescriptions['forwardmap'], 

'reversemap': defaultPartDescriptions['reversemap'], 

'grid': defaultPartDescriptions['grid'], 

'wavelength': defaultPartDescriptions['wavelength']} 

preferredSlicing = {'radiance': ('spectral',), 

'previewdata': ('color',)} 

 

computeComplexity = 8 

componentCount = 1 

 

def query(self, alignedImage): 

alignedImage.productType == 'aligned_image' 

 

44 ↛ exitline 44 didn't run the lambda on line 44 sensorId = pprop(lambda alignedImage: alignedImage.sensorId) 

45 ↛ exitline 45 didn't run the lambda on line 45 startTime = pprop(lambda alignedImage: alignedImage.startTime) 

46 ↛ exitline 46 didn't run the lambda on line 46 stopTime = pprop(lambda alignedImage: alignedImage.stopTime) 

47 ↛ exitline 47 didn't run the lambda on line 47 date = pprop(lambda alignedImage: alignedImage.date) 

48 ↛ exitline 48 didn't run the lambda on line 48 integrationTime = pprop(lambda alignedImage: alignedImage.integrationTime) 

49 ↛ exitline 49 didn't run the lambda on line 49 userMeta = pprop(lambda alignedImage: alignedImage.userMeta) 

 

@pprop 

def dataSize(self, alignedImage): 

xSize, ySize = self._getGrid().shape[1:] 

#TODO: normally this should not happen, search for the root cause! 

if xSize*ySize == 0: 

raise ValueError('projection has szie of 0!') 

return {'x': xSize, 

'y': ySize, 

'spectral': alignedImage.dataSize['spectral'], 

'color': alignedImage.dataSize['color'], 

'xy': 2, 

'sourcepixels': alignedImage.dataSize['frames'] * alignedImage.dataSize['spatial']} 

 

@returns('float32') 

def _getRadianceBySpectral(self, start, stop): 

pv = self.components['alignedImage']['radiance'].T('spectral').S(start, stop) 

reverseMap = self['reversemap'].get() 

mask = reverseMap<self.dataSize['sourcepixels'] 

reverseMap = np.where(mask, reverseMap, 0) 

for block in pv: 

yield (np.ravel(block)[reverseMap])*mask 

 

@cacheable 

@returns('uint8') 

def _getPreviewdataByColor(self, start, stop): 

pv = self.components['alignedImage']['previewdata'].T('color').S(start, stop) 

reverseMap = self['reversemap'].get() 

mask = reverseMap<self.dataSize['sourcepixels'] 

reverseMap = np.where(mask, reverseMap, 0) 

for block in pv: 

yield (np.ravel(block)[reverseMap])*mask 

 

@cacheable 

@returns('int64') 

def _getReversemap(self): 

import scipy.spatial 

kdt = scipy.spatial.cKDTree(zip(*self['forwardmap'].get())) 

queryGrid = self['grid'].get().transpose(1,2,0) 

_, indices = kdt.query(queryGrid, distance_upper_bound=(5. * self.pixelSize)) 

return indices 

 

@returns('float32') 

def _getWavelength(self): 

#nasty workaround, because np.nanmean is not available in numpy < 1.8.0 

wavelength = self.components['alignedImage']['wavelength'].get() 

wavelengthMean = np.zeros(wavelength.shape[1], dtype='float32') 

for i, d in enumerate(wavelength.T): 

wavelengthMean[i] = np.mean(d[np.isfinite(d)]) 

return wavelengthMean