Commit c1e5a5d20ba24c9f153a1b72e96b882a9a127d3d

Authored by Arthur VINCENT
1 parent 0e649bc0

DOC : documentation update

config/Config_4Tuiles_Multi_FUS_Confidence.cfg
... ... @@ -12,7 +12,7 @@ chain:
12 12 pyAppPath:'/home/user13/theia_oso/vincenta/THEIA_OSO/oso/theia_oso/scripts/common'
13 13 chainName:'OSO_chain_CONFID'
14 14 nomenclaturePath:'/home/user13/theia_oso/vincenta/Nomenclature_SudFrance.csv'
15   - outputStatistics:'True'
  15 + outputStatistics:True
16 16  
17 17 listTile:'D0004H0004 D0005H0004 D0004H0003 D0005H0003'
18 18 featuresPath:'/ptmp/vincenta/TILES_2014_v4/'
... ... @@ -41,7 +41,7 @@ chain:
41 41 logFileLevel:"INFO"
42 42  
43 43 colorTable:'/home/user13/theia_oso/vincenta/THEIA_OSO/oso/theia_oso/doc/colorFile.txt'
44   - mode_outside_RegionSplit:''#square km
  44 + mode_outside_RegionSplit:0.1#square km
45 45  
46 46 OTB_HOME:'/data/qtis/inglada/modules/repository/otb_superbuild/otb_superbuild-5.2.1-Release-install/'
47 47 }
... ... @@ -52,27 +52,25 @@ chain:
52 52  
53 53 argTrain:
54 54 {
55   -
56 55 sampleSelection : {"sampler":random,
57 56 "strategy":percent,
58 57 "strategy.percent.p":0.2,
59   - "ram":"4000",
60   - "per_models":[{"target_model":"4",
  58 + "ram":4000,
  59 + "per_models":[{"target_model":4,
61 60 "sampler":"periodic"}]
62 61 }
63 62  
64 63 classifier :'rf'
65 64 options :' -classifier.rf.min 5 -classifier.rf.max 25 '
66 65  
67   - cropMix:'False'
  66 + cropMix:False
68 67 prevFeatures:'/ptmp/vincenta/TestCropMix/2013/config_2013.cfg'
69 68 outputPrevFeatures:'/work/OT/theia/oso/features/L8_2014_features/'
70 69 annualCrop:['11','12']
71 70 ACropLabelReplacement:['10','annualCrop']
72   - samplesClassifMix:'False'
  71 + samplesClassifMix:False
73 72 annualClassesExtractionSource:'/path/to/theConfigurationFileWhichRuleAPreviousClassification'
74   - validityThreshold : '5'
75   - coeffSampleSelection : '1'
  73 + validityThreshold : 5
76 74 }
77 75  
78 76 ################################################################################################
... ... @@ -84,7 +82,6 @@ argClassification:
84 82 classifMode :'fusion'#fusion or separate
85 83 fusionOptions :'-nodatalabel 0 -method majorityvoting'
86 84 pixType : 'uint8'
87   - confusionModel : False #True or False
88 85 noLabelManagement : 'maxConfidence'#maxConfidence or learningPriority
89 86 }
90 87  
... ... @@ -93,7 +90,7 @@ argClassification:
93 90 ################################################################################################
94 91 Landsat8:
95 92 {
96   - nodata_Mask : "False"
  93 + nodata_Mask : False
97 94 nativeRes : 30
98 95 arbo : "/*/*"
99 96 imtype : "ORTHO_SURF_CORR_PENTE*.TIF"
... ... @@ -104,13 +101,13 @@ Landsat8:
104 101 arbomask : "*/*/MASK/"
105 102 startDate:''
106 103 endDate:''
107   - temporalResolution:'16'
  104 + temporalResolution:16
108 105 additionalFeatures:"b1+b2,(b1-b2)/(b1+b2)"#comma splited
109 106 keepBands:[[1,"blue"],[2,"green"],[3,"red"],[7,"NIR"],[9,"SWIR"]]
110 107 }
111 108 Landsat5:
112 109 {
113   - nodata_Mask : "False"
  110 + nodata_Mask : False
114 111 nativeRes : 30
115 112 arbo : "/*/*"
116 113 imtype : "ORTHO_SURF_CORR_PENTE*.TIF"
... ... @@ -121,13 +118,13 @@ Landsat5:
121 118 arbomask : "*/*/MASK/"
122 119 startDate:''
123 120 endDate:''
124   - temporalResolution:'16'
  121 + temporalResolution:16
125 122 additionalFeatures:"b1+b2,(b1-b2)/(b1+b2)"#comma splited
126 123 keepBands:[[1,"blue"],[2,"green"],[3,"red"],[7,"NIR"],[9,"SWIR"]]
127 124 }
128 125 Sentinel_2:
129 126 {
130   - nodata_Mask : ""
  127 + nodata_Mask : False
131 128 nativeRes : 10
132 129 arbo : "/*/"
133 130 imtype : "*STACK.tif"
... ... @@ -141,7 +138,7 @@ Sentinel_2:
141 138 arbomask : "/*/MASKS/"
142 139 startDate:''
143 140 endDate:''
144   - temporalResolution:'10'
  141 + temporalResolution:10
145 142 additionalFeatures:"b1+b2,(b1-b2)/(b1+b2)"#comma splited
146 143 keepBands:[[1,"blue"],[2,"green"],[3,"red"],[7,"NIR"],[9,"SWIR"]]
147 144 }
... ... @@ -154,17 +151,17 @@ GlobChain:
154 151 {
155 152 proj : "EPSG:2154"
156 153 features: ["NDVI","NDWI","Brightness"]
157   - autoDate:'True'
158   - writeOutputs:'False'
159   - useAdditionalFeatures:'True'
160   - useGapFilling:'True'
  154 + autoDate:True
  155 + writeOutputs:False
  156 + useAdditionalFeatures:True
  157 + useGapFilling:True
161 158 }
162 159  
163 160 iota2FeatureExtraction:
164 161 {
165   - copyinput:'True'
166   - relrefl:'False'
167   - keepduplicates:'False'
168   - extractBands:'False'
  162 + copyinput:True
  163 + relrefl:False
  164 + keepduplicates:False
  165 + extractBands:False
169 166 }
170 167 ################################################################################################
... ...
doc/running_iota.org
... ... @@ -78,8 +78,8 @@ This part corresponds to the general description of the test.
78 78 | ratio | Training and validation sample ratio | must be a float between [0;1] | ratio:0.5 |
79 79 | cloud_treshold | a valid pixel is a pixel which is less "cloud_treshold" under clouds | must be an integer >= 0 | cloud_threshold:1 |
80 80 | spatialResolution | output pixel's spatial resolution | - | spatialResolution:30 |
81   -| firstStep | parameter use to restart chain from a specific step. Available choices are init,sampling,learning,classification,mosaic or validation | must be chosen into the list of available steps | firstStep:init |
82   -| lastStep | parameter use to stop chain from a specific step. Available choices are init,sampling,learning,classification,mosaic or validation | must be chosen into the list of available steps | lastStep:validation |
  81 +| firstStep | parameter use to restart chain from a specific step. Available choices are init,sampling,learning,classification,mosaic or validation | must be chosen into the list of available steps | firstStep:"init" |
  82 +| lastStep | parameter use to stop chain from a specific step. Available choices are init,sampling,learning,classification,mosaic or validation | must be chosen into the list of available steps | lastStep:"validation" |
83 83  
84 84 (1) Example of file describing nomenclature
85 85  
... ... @@ -140,24 +140,23 @@ This part is dedicated to the learning mode.
140 140 |-------------------------------+------------------------------------------------------------------------+---------------------------------------------------+---------------------------------------------|
141 141 | classifier | the classifier asks | should exist in OTB | classifier : 'rf' |
142 142 | options | classifier options | should exist in OTB | options : '-classifier.rf.min 5' |
143   -| cropMix | flag to use previous crop datas | must be 'True' or 'False' | cropMix:'True' |
  143 +| cropMix | flag to use previous crop datas | must be True or False | cropMix:True |
144 144 | prevFeatures | path to a configuration file which is able to produce annual features | must be a string | prevFeatures:'/../2013/config_2013.cfg' |
145 145 | outputPrevFeatures | path to store features extract from prevFeatures | must be a string | outputPrevFeatures:'../2013/' |
146 146 | annualCrop | crop's class number | must be a list of string and exist in groundTruth | annualCrop:['11','12'] |
147 147 | ACropLabelReplacement | list which contains a label and a name to replace annual crop | must be a list | ACropLabelReplacement:['10','annualCrop'] |
148   -| samplesClassifMix | flag to pick annual crop in a previous classificaiton | must be 'True' or 'Flase' | samplesClassifMix:'True' |
  148 +| samplesClassifMix | flag to pick annual crop in a previous classificaiton | must be True or False | samplesClassifMix:True |
149 149 | annualClassesExtractionSource | path to a previous run of IOTA2 (use if samplesClassif is set to True) | must be a string | configClassif:'/path/to/aPreviousIOTA2_run' |
150   -| validityTreshold | chose pixels only if validity > threshold | must be a int string | validityThreshold:'5' |
151   -| coeffSampleSelection | in samplesClassifMix, percentage of annualCrop to pick up | string between [0,1] | coeffSampleSelection:'1' |
  150 +| validityTreshold | chose pixels only if validity > threshold | must be an integer | validityThreshold:5 |
152 151 | sampleSelection | parameter to set sample selection strategies | python dictionnary format | (1) |
153 152  
154 153 (1)
155 154 #+BEGIN_EXAMPLE python
156   -sampleSelection : {"sampler":random,
157   - "strategy":percent,
  155 +sampleSelection : {"sampler":"random",
  156 + "strategy":"percent",
158 157 "strategy.percent.p":0.2,
159   - "ram":"4000",
160   - "per_models":[{"target_model":"4",
  158 + "ram":4000,
  159 + "per_model":[{"target_model":4,
161 160 "sampler":"periodic"},
162 161 {"target_model":"2",
163 162 "sampler":"periodic",
... ... @@ -178,8 +177,7 @@ Classification's options
178 177 |-------------------+---------------------------------------------------------------------------------+---------------------------------------------+---------------------------------------------------------|
179 178 | classifMode | argument uses in order to indicate if fusion of classification will be used (1) | must be 'fusion' or 'seperate' | classifMode : 'fusion' |
180 179 | fusionOptions | parameters for fusion of classification | these parameters must exist in OTB | fusionOptions : '-nodatalabel 0 -method majorityvoting' |
181   -| pixType | the type of the output pixel in classification | - | pixType : 'int8' |
182   -| confusionModel | argument use to indicate if you also want a confusion matrix by model | must be False or True | confusionModel:False |
  180 +| pixType | output classification's pixel format | - | pixType : 'uint8' |
183 181 | noLabelManagement | use to indice how to manage Nolabels (in fusion mode) (2) | must be 'maxConfidence' or learningPriority | noLabelManagement:'maxConfidence' |
184 182  
185 183 (1) Explanation about classifMode's options
... ... @@ -202,34 +200,33 @@ Classification's options
202 200  
203 201 Today, features computable are : NDVI, NDWI and the brightness. Only two sensors are supported, Landsat_8 and Landsat_5, but some others are coming soon. So you only have to fill out the Landsat_8 block composed by many fields.
204 202  
205   -| field | Description | Conditions | Example |
206   -|-----------------------+--------------------------------------------------------------------------------------------------------------+----------------------------------------------------+------------------------------------------------------------------------------|
207   -| nodata_Mask | argument used to indicate if a NoData mask exists | must be 'False' or 'True' | nodata_Mask : 'False' |
208   -| nativeRes | native resolution of images | must be an integer | nativeRes : 30 |
209   -| arbo | inform the image's path, according to L8Path (1) | - | arbo : /*/* |
210   -| imtype | allow you to target a specific images in arbo | - | imtype : "ORTHO_SURF_CORR_PENTE*.TIF" |
211   -| arbomask | inform the path of the mask link to the image, according to L8Path | - | arbomask : "*/*/MASK/" |
212   -| nuages | target the mask of cloud in arbomask | - | nuages : "NUA.TIF" |
213   -| saturation | target the mask of saturation in arbomask | - | saturation : "SAT.TIF" |
214   -| div | target the mask of diverse in arbomask | - | div : "DIV.TIF" |
215   -| nodata | target the nodata mask in arbomask | - | nodata : "NODATA.TIF" if nodata_Mask is set to 'False', nodata could be : "" |
216   -| features | describre which features uses | must be a list of strings (2) | features: ["NDVI","NDWI","Brightness"] |
217   -| nbLook | number of data available needed to consider a pixel to produce features | must be an integer >= 1 | nbLook:1 |
218   -| proj | output projection | must be an EPSG code | proj:"EPSG:2154" |
219   -| temporalResolution | temporal resolution in order to manage gapfilling (cloud management) | - | temporalResolution:'16'#Landsat8 case |
220   -| autoDate | force gapfilling's output date or not | must be 'True' or 'False' | autoDate:'True' |
221   -| startDate | starting date to use in gapfilling ouput | must be 'YYYYMMDD' | startDate:'20150121' |
222   -| endDate | ending date to use in gapfilling ouput | must be 'YYYYMMDD' | endDate:'20151205' |
223   -| patterns | in user's features, pattern to chose features | - | patterns:'ALT,MNT' |
224   -| extractBands | flag to use targeted bands if not use (False) -> all bands are used | must be 'True' or 'False' | extractBands:'False' |
225   -| keepBands | bands to keep to produce features | must respect Sensors.py definition (4) | keepBands:[[1,"blue"],[2,"green"],[3,"red"],[7,"NIR"],[9,"SWIR"]] |
226   -| copyinput | if bindingPython is set to 'True', use sensor's data and derivated ceofficient | must be 'True' or 'False' | copyinput:'True' |
227   -| relrefl | normalize bands by the red band SWIR_norm = (SWIR-RED)/(SWIR+RED) | must be 'True' or 'False' | relrefl:'False' |
228   -| keepduplicates | using red normalization could introduce duplicate data, set keepduplicate to 'False' remove duplicates bands | must be 'True' or 'False' | keepduplicates:'False' |
229   -| additionalFeatures | user features definition | must be a bandMath (OTB) expression, comma splited | additionalFeatures:"b1+b2,(b1-b2)/(b1+b2)" |
230   -| useAdditionalFeatures | flag to indicate if the chain must use 'additionalFeatures' | must be 'True' or 'False' | useAdditionalFeatures:'False' |
231   -| writeOutputs | flag to indicate if temporary files musk be written on disk (faster if set to 'False') | must be 'True' or 'False' | writeOutputs:'False' |
232   -| useGapFilling | flag to use temporal interpolation | must be 'True' or 'False' | useGapFilling : 'True' |
  203 +| field | Description | Conditions | Example |
  204 +|-----------------------+--------------------------------------------------------------------------------------------------------------+----------------------------------------------------+----------------------------------------------------------------------------|
  205 +| nodata_Mask | argument used to indicate if a NoData mask exists | must be False or True | nodata_Mask : False |
  206 +| nativeRes | native resolution of images | must be an integer | nativeRes : 30 |
  207 +| arbo | inform the image's path, according to L8Path (1) | - | arbo : /*/* |
  208 +| imtype | allow you to target a specific images in arbo | - | imtype : "ORTHO_SURF_CORR_PENTE*.TIF" |
  209 +| arbomask | inform the path of the mask link to the image, according to L8Path | - | arbomask : "*/*/MASK/" |
  210 +| nuages | target the mask of cloud in arbomask | - | nuages : "NUA.TIF" |
  211 +| saturation | target the mask of saturation in arbomask | - | saturation : "SAT.TIF" |
  212 +| div | target the mask of diverse in arbomask | - | div : "DIV.TIF" |
  213 +| nodata | target the nodata mask in arbomask | - | nodata : "NODATA.TIF" if nodata_Mask is set to False, nodata could be : "" |
  214 +| features | describre which features uses | must be a list of strings (2) | features: ["NDVI","NDWI","Brightness"] |
  215 +| proj | output projection | must be an EPSG code | proj:"EPSG:2154" |
  216 +| temporalResolution | temporal resolution in order to manage gapfilling (cloud management) | - | temporalResolution:16 |
  217 +| autoDate | force gapfilling's output date or not | must be True or False | autoDate:True |
  218 +| startDate | starting date to use in gapfilling ouput | must be 'YYYYMMDD' | startDate:'20150121' |
  219 +| endDate | ending date to use in gapfilling ouput | must be 'YYYYMMDD' | endDate:'20151205' |
  220 +| patterns | in user's features, pattern to chose features | - | patterns:'ALT,MNT' |
  221 +| extractBands | flag to use targeted bands if not use (False) -> all bands are used | must be True or False | extractBands:False |
  222 +| keepBands | bands to keep to produce features | must respect Sensors.py definition (4) | keepBands:[[1,"blue"],[2,"green"],[3,"red"],[7,"NIR"],[9,"SWIR"]] |
  223 +| copyinput | if bindingPython is set to 'True', use sensor's data and derivated ceofficient | must be True or False | copyinput:True |
  224 +| relrefl | normalize bands by the red band SWIR_norm = (SWIR-RED)/(SWIR+RED) | must be True or False | relrefl:False |
  225 +| keepduplicates | using red normalization could introduce duplicate data, set keepduplicate to 'False' remove duplicates bands | must be True or False | keepduplicates:False |
  226 +| additionalFeatures | user features definition | must be a bandMath (OTB) expression, comma splited | additionalFeatures:"b1+b2,(b1-b2)/(b1+b2)" |
  227 +| useAdditionalFeatures | flag to indicate if the chain must use 'additionalFeatures' | must be True or False | useAdditionalFeatures:False |
  228 +| writeOutputs | flag to indicate if temporary files musk be written on disk (faster if set to 'False') | must be True or False | writeOutputs:False |
  229 +| useGapFilling | flag to use temporal interpolation | must be True or False | useGapFilling : True |
233 230  
234 231  
235 232  
... ... @@ -309,6 +306,8 @@ Each chain creates a tree folder, from the path given in field output, as descri
309 306 │   └── commands uses in order to generate models
310 307 ├── dataAppVal
311 308 │   └── ground truth uses to learn models and during validation phase
  309 +├── SampleSelection
  310 +│   └── samples use to learn models (withou features)
312 311 ├── dataRegion
313 312 │   └── ground truth before the split learn-val
314 313 ├── envelope
... ... @@ -317,7 +316,7 @@ Each chain creates a tree folder, from the path given in field output, as descri
317 316 │   ├── final classification with and without color indexation
318 317 │   ├── RESULTS.txt
319 318 │   └── TMP
320   -│   └── some tmp results
  319 +│   └── some tmp data
321 320 ├── model
322 321 │   └── models generate during learning phase
323 322 ├── shapeRegion
... ...
scripts/common/Sensors.py
... ... @@ -66,7 +66,7 @@ class Landsat5(Sensor):
66 66 self.nir = self.bands["BANDS"]['B4']
67 67 self.swir = self.bands["BANDS"]['B5']
68 68  
69   - if sensorEnable and cfg.iota2FeatureExtraction.extractBands == 'True':
  69 + if sensorEnable and cfg.iota2FeatureExtraction.extractBands == True:
70 70 self.keepBands = OrderedDict([(k, v) for k, v in self.bands["BANDS"].items() if k in conf.keepBands])
71 71 if cfg.GlobChain.features:
72 72 try:
... ... @@ -187,7 +187,7 @@ class Landsat8(Sensor):
187 187 self.nir = self.bands["BANDS"]['B5']
188 188 self.swir = self.bands["BANDS"]['B6']
189 189  
190   - if sensorEnable and cfg.iota2FeatureExtraction.extractBands == 'True':
  190 + if sensorEnable and cfg.iota2FeatureExtraction.extractBands == True:
191 191 self.keepBands = OrderedDict([(k, v) for k, v in self.bands["BANDS"].items() if k in conf.keepBands])
192 192 if cfg.GlobChain.features:
193 193 try:
... ... @@ -300,7 +300,7 @@ class Sentinel_2(Sensor):
300 300 self.swir = self.bands["BANDS"]['B11']
301 301  
302 302 self.keepBands = None
303   - if sensorEnable and cfg.iota2FeatureExtraction.extractBands == 'True':
  303 + if sensorEnable and cfg.iota2FeatureExtraction.extractBands == True:
304 304 self.keepBands = OrderedDict([(k, v) for k, v in self.bands["BANDS"].items() if k in conf.keepBands])
305 305 if cfg.GlobChain.features:
306 306 try:
... ...
scripts/common/fileUtils.py
... ... @@ -596,11 +596,11 @@ def iota2FeatureExtractionParameter(otbObject, cfg):
596 596 relrefl = cfg.getParam('iota2FeatureExtraction', 'relrefl')
597 597 keepduplicates = cfg.getParam('iota2FeatureExtraction', 'keepduplicates')
598 598  
599   - if copyinput == "True":
  599 + if copyinput == True:
600 600 otbObject.SetParameterEmpty("copyinput", True)
601   - if relrefl == "True":
  601 + if relrefl == True:
602 602 otbObject.SetParameterEmpty("relrefl", True)
603   - if keepduplicates == "True":
  603 + if keepduplicates == True:
604 604 otbObject.SetParameterEmpty("keepduplicates", True)
605 605  
606 606  
... ...
scripts/common/iota2tests_features_labels.py
... ... @@ -63,10 +63,10 @@ class iota_test_Basic(unittest.TestCase):
63 63 this tests group check feature's labels with basic runs
64 64 parameters are set as follow :
65 65  
66   - copyinput:'True'
67   - relrefl:'False'
68   - keepduplicates:'False'
69   - extractBands:'False'
  66 + copyinput:True
  67 + relrefl:False
  68 + keepduplicates:False
  69 + extractBands:False
70 70 """
71 71 currenResult = None
72 72  
... ...
scripts/common/otbAppli.py
... ... @@ -1336,7 +1336,7 @@ def gapFilling(cfg, tile, wMode, featuresPath=None, workingDirectory=None,
1336 1336 if userFeatPath == "None":
1337 1337 userFeatPath = None
1338 1338 extractBands = cfg.getParam('iota2FeatureExtraction', 'extractBands')
1339   - if extractBands == "False":
  1339 + if extractBands == False:
1340 1340 extractBands = None
1341 1341  
1342 1342 ipathL5 = cfg.getParam('chain', 'L5Path')
... ... @@ -1767,7 +1767,7 @@ def computeFeatures(cfg, nbDates, tile, stack_dates, AllRefl, AllMask,
1767 1767  
1768 1768 all_fields_sens = []
1769 1769 useAddFeat = cfg.getParam('GlobChain', 'useAdditionalFeatures')
1770   - extractBands = ast.literal_eval(cfg.getParam('iota2FeatureExtraction', 'extractBands'))
  1770 + extractBands = cfg.getParam('iota2FeatureExtraction', 'extractBands')
1771 1771 #does not work in operational context (alway empty) -> but test pass...
1772 1772 #featuresFlag = cfg.getParam('GlobChain', 'features')
1773 1773 featuresFlag = Config(pathConf).GlobChain.features
... ... @@ -1832,7 +1832,7 @@ def computeFeatures(cfg, nbDates, tile, stack_dates, AllRefl, AllMask,
1832 1832 all_fields_sens.append(fields_userFeat)
1833 1833  
1834 1834 fields = fields_names(currentSensor, datesFile=c_datesFile_sensor,
1835   - iota2FeatExtApp=featExtr, ext_Bands_Flag = extractBands)
  1835 + iota2FeatExtApp=featExtr, ext_Bands_Flag=extractBands)
1836 1836  
1837 1837 all_fields_sens.append(fields)
1838 1838  
... ...
scripts/common/serviceConfigFile.py
... ... @@ -293,6 +293,11 @@ class serviceConfigFile:
293 293 self.testVarConfigFile('GlobChain', 'useAdditionalFeatures', bool)
294 294 self.testVarConfigFile('GlobChain', 'useGapFilling', bool)
295 295  
  296 + self.testVarConfigFile('iota2FeatureExtraction', 'copyinput', bool)
  297 + self.testVarConfigFile('iota2FeatureExtraction', 'relrefl', bool)
  298 + self.testVarConfigFile('iota2FeatureExtraction', 'keepduplicates', bool)
  299 + self.testVarConfigFile('iota2FeatureExtraction', 'extractBands', bool)
  300 +
296 301 if self.cfg.chain.L5Path != "None":
297 302 #L5 variable check
298 303 self.testVarConfigFile('Landsat5', 'nodata_Mask', bool)
... ...
scripts/common/vectorSampler.py
... ... @@ -661,7 +661,6 @@ def generateSamples_classifMix(folderSample, workingDirectory, trainShape,
661 661 userFeatPath = cfg.getParam('chain', 'userFeatPath')
662 662 features_path = cfg.getParam('chain', 'featuresPath')
663 663 outFeatures = cfg.getParam('GlobChain', 'features')
664   - extractBands = cfg.getParam('iota2FeatureExtraction', 'extractBands')
665 664 runs = cfg.getParam('chain', 'runs')
666 665 regionField = (cfg.getParam('chain', 'regionField')).lower()
667 666 outputPath = cfg.getParam('chain', 'outputPath')
... ...