Commit 63661f50eaf9b47ab13ac11dd48cec9e5f091584
1 parent
49bfb301
Test all residual map algorithms in csresmap (#1828)
Showing
2 changed files
with
123 additions
and
158 deletions
cscripts/csresmap.py
| ... | ... | @@ -28,12 +28,7 @@ import ctools |
| 28 | 28 | # ============== # |
| 29 | 29 | class csresmap(ctools.cscript): |
| 30 | 30 | """ |
| 31 | - Generates a residual map. | |
| 32 | - | |
| 33 | - This class implements the creation of a residual map. It derives from | |
| 34 | - the ctools.cscript class which provides support for parameter files, | |
| 35 | - command line arguments, and logging. In that way the Python script | |
| 36 | - behaves just as a regular ctool. | |
| 31 | + Generates a residual map | |
| 37 | 32 | """ |
| 38 | 33 | |
| 39 | 34 | # Constructor |
| ... | ... | @@ -42,42 +37,18 @@ class csresmap(ctools.cscript): |
| 42 | 37 | Constructor. |
| 43 | 38 | """ |
| 44 | 39 | # Set name |
| 45 | - self._name = "csresmap" | |
| 46 | - self._version = "1.1.0" | |
| 40 | + self._name = 'csresmap' | |
| 41 | + self._version = '1.1.0' | |
| 47 | 42 | |
| 48 | 43 | # Initialise class members |
| 49 | - self._algorithm = "SUB" | |
| 50 | 44 | self._resmap = None |
| 51 | - self._modcube = "NONE" | |
| 52 | 45 | self._use_maps = False |
| 53 | 46 | self._skip_binning = False |
| 54 | - self._publish = False | |
| 55 | - self._outfile = "" | |
| 56 | - self._use_maps = False | |
| 57 | - self._skip_binning = False | |
| 58 | - self._edisp = False | |
| 59 | - self._xref = 83.63 | |
| 60 | - self._yref = 22.01 | |
| 61 | - self._emin = 0.1 | |
| 62 | - self._emax = 100.0 | |
| 63 | - self._enumbins = 0 | |
| 64 | - self._ebinalg = "LOG" | |
| 65 | - self._coordsys = "CEL" | |
| 66 | - self._proj = "CAR" | |
| 67 | - self._nxpix = 200 | |
| 68 | - self._nypix = 200 | |
| 69 | - self._binsz = 0.02 | |
| 70 | - self._publish = False | |
| 71 | - self._chatter = 2 | |
| 72 | - self._clobber = True | |
| 73 | - self._debug = False | |
| 74 | - self._log_clients = False | |
| 75 | - | |
| 76 | - # Initialise observation container from constructor arguments. | |
| 47 | + | |
| 48 | + # Initialise observation container from constructor arguments | |
| 77 | 49 | self._obs, argv = self._set_input_obs(argv) |
| 78 | 50 | |
| 79 | - # Initialise application by calling the appropriate class | |
| 80 | - # constructor. | |
| 51 | + # Initialise application by calling the appropriate class constructor | |
| 81 | 52 | self._init_cscript(argv) |
| 82 | 53 | |
| 83 | 54 | # Return |
| ... | ... | @@ -87,25 +58,29 @@ class csresmap(ctools.cscript): |
| 87 | 58 | # Private methods |
| 88 | 59 | def _get_parameters(self): |
| 89 | 60 | """ |
| 90 | - Get parameters from parfile and setup the observation. | |
| 61 | + Get parameters from parfile and setup the observation | |
| 91 | 62 | """ |
| 92 | 63 | # Initialise some flags |
| 93 | 64 | self._use_maps = False |
| 94 | 65 | self._skip_binning = False |
| 95 | 66 | |
| 96 | - # First check if the inobs parameter is a counts cube | |
| 97 | - if self._obs.size() == 0 and self["inobs"].filename() != "NONE": | |
| 98 | - filename = gammalib.GFilename(self["inobs"].filename()) | |
| 67 | + # If there are no observations in the observation container then check | |
| 68 | + # if the "inobs" parameter is a counts cube. If the "inobs" parameter | |
| 69 | + # represents a FITS file and if this FITS file is a counts cube then | |
| 70 | + # set self._skip_binning=True | |
| 71 | + if self._obs.size() == 0 and self['inobs'].filename() != 'NONE': | |
| 72 | + filename = gammalib.GFilename(self['inobs'].filename()) | |
| 99 | 73 | if filename.is_fits(): |
| 100 | 74 | cta = gammalib.GCTAObservation() |
| 101 | 75 | cta.load(filename) |
| 102 | - if cta.eventtype() == "CountsCube": | |
| 76 | + if cta.eventtype() == 'CountsCube': | |
| 103 | 77 | self._skip_binning = True |
| 104 | 78 | |
| 105 | - # If we have a counts cube, then ask whether we also have a model | |
| 79 | + # If we have a counts cube, then ask whether we also have a model cube. | |
| 80 | + # If a model cube name is given then set self._use_maps=True | |
| 106 | 81 | if self._skip_binning: |
| 107 | - self._modcube = self["modcube"].filename() | |
| 108 | - if self._modcube != "NONE": | |
| 82 | + modcube = self['modcube'].filename() | |
| 83 | + if modcube != 'NONE': | |
| 109 | 84 | self._use_maps = True |
| 110 | 85 | |
| 111 | 86 | # If not two maps are given, proceed to set up observation |
| ... | ... | @@ -113,56 +88,51 @@ class csresmap(ctools.cscript): |
| 113 | 88 | |
| 114 | 89 | # Set observation if not done before |
| 115 | 90 | if self._obs.size() == 0: |
| 116 | - self._require_inobs("csresmap.get_parameters()") | |
| 91 | + self._require_inobs('csresmap.get_parameters()') | |
| 117 | 92 | self._obs = self._get_observations() |
| 118 | 93 | |
| 119 | - # Check if we have exactly one binned CTA observation | |
| 120 | - if self._obs.size() == 1: | |
| 121 | - | |
| 122 | - if self._obs[0].classname() == "GCTAObservation": | |
| 123 | - if self._obs[0].eventtype() == "CountsCube": | |
| 124 | - # Skip ctbin step later on | |
| 125 | - self._skip_binning = True | |
| 94 | + # If we have exactly one binned CTA observation then signal that | |
| 95 | + # the binning can be skipped | |
| 96 | + if self._obs.size() == 1 and \ | |
| 97 | + self._obs[0].classname() == 'GCTAObservation' and \ | |
| 98 | + self._obs[0].eventtype() == 'CountsCube': | |
| 99 | + self._skip_binning = True | |
| 126 | 100 | |
| 127 | 101 | # Set models if we have none |
| 128 | 102 | if self._obs.models().size() == 0: |
| 129 | - self._obs.models(self["inmodel"].filename()) | |
| 103 | + self._obs.models(self['inmodel'].filename()) | |
| 130 | 104 | |
| 131 | - # Skip query for spatial parameters if a binning is provided in the observation | |
| 105 | + # If no binning is provided in the observation then query now | |
| 106 | + # the counts cube binning parameters | |
| 132 | 107 | if not self._skip_binning: |
| 133 | - # Read other parameters | |
| 134 | - self._xref = self["xref"].real() | |
| 135 | - self._yref = self["yref"].real() | |
| 136 | - self._emin = self["emin"].real() | |
| 137 | - self._emax = self["emax"].real() | |
| 138 | - self._enumbins = self["enumbins"].integer() | |
| 139 | - self._ebinalg = self["ebinalg"].string() | |
| 140 | - self._coordsys = self["coordsys"].string() | |
| 141 | - self._proj = self["proj"].string() | |
| 142 | - self._nxpix = self["nxpix"].integer() | |
| 143 | - self._nypix = self["nypix"].integer() | |
| 144 | - self._binsz = self["binsz"].real() | |
| 108 | + self['xref'].real() | |
| 109 | + self['yref'].real() | |
| 110 | + self['emin'].real() | |
| 111 | + self['emax'].real() | |
| 112 | + self['enumbins'].integer() | |
| 113 | + self['ebinalg'].string() | |
| 114 | + self['coordsys'].string() | |
| 115 | + self['proj'].string() | |
| 116 | + self['nxpix'].integer() | |
| 117 | + self['nypix'].integer() | |
| 118 | + self['binsz'].real() | |
| 145 | 119 | |
| 146 | - # Read energy dispersion flag | |
| 147 | - self._edisp = self["edisp"].boolean() | |
| 148 | - | |
| 149 | - # Read algorithm | |
| 150 | - self._algorithm = self["algorithm"].string() | |
| 151 | - | |
| 152 | - # Read standard parameters | |
| 153 | - self._publish = self["publish"].boolean() | |
| 154 | - self._chatter = self["chatter"].integer() | |
| 155 | - self._clobber = self["clobber"].boolean() | |
| 156 | - self._debug = self["debug"].boolean() | |
| 157 | - | |
| 158 | - # Read ahead output parameters | |
| 120 | + # Query parameters | |
| 121 | + self['edisp'].boolean() | |
| 122 | + self['algorithm'].string() | |
| 123 | + self['publish'].boolean() | |
| 124 | + self['chatter'].integer() | |
| 125 | + self['clobber'].boolean() | |
| 126 | + self['debug'].boolean() | |
| 127 | + | |
| 128 | + # Query ahead output parameters | |
| 159 | 129 | if (self._read_ahead()): |
| 160 | - self["outmap"].filename() | |
| 130 | + self['outmap'].filename() | |
| 161 | 131 | |
| 162 | 132 | # Write input parameters into logger |
| 163 | 133 | if self._logTerse(): |
| 164 | 134 | self._log_parameters() |
| 165 | - self._log("\n") | |
| 135 | + self._log('\n') | |
| 166 | 136 | |
| 167 | 137 | # Return |
| 168 | 138 | return |
| ... | ... | @@ -171,7 +141,7 @@ class csresmap(ctools.cscript): |
| 171 | 141 | # Public methods |
| 172 | 142 | def run(self): |
| 173 | 143 | """ |
| 174 | - Run the script. | |
| 144 | + Run the script | |
| 175 | 145 | """ |
| 176 | 146 | # Switch screen logging on in debug mode |
| 177 | 147 | if self._logDebug(): |
| ... | ... | @@ -182,46 +152,48 @@ class csresmap(ctools.cscript): |
| 182 | 152 | |
| 183 | 153 | # Write observation into logger |
| 184 | 154 | if self._logTerse(): |
| 185 | - self._log("\n") | |
| 186 | - self._log.header1("Observation") | |
| 155 | + self._log('\n') | |
| 156 | + self._log.header1(gammalib.number('Observation',len(self._obs))) | |
| 187 | 157 | self._log(str(self._obs)) |
| 188 | - self._log("\n") | |
| 158 | + self._log('\n') | |
| 189 | 159 | |
| 190 | - # Use input file directly if given | |
| 160 | + # If a counts and model cube are specified then load them as sky map | |
| 191 | 161 | if self._use_maps: |
| 192 | - countmap = gammalib.GSkyMap(self["inobs"].filename()) | |
| 193 | - modelmap = gammalib.GSkyMap(self._modcube) | |
| 162 | + countmap = gammalib.GSkyMap(self['inobs'].filename()) | |
| 163 | + modelmap = gammalib.GSkyMap(self['modcube'].filename()) | |
| 194 | 164 | |
| 165 | + # ... otherwise build a counts cube and model cube | |
| 195 | 166 | else: |
| 196 | 167 | |
| 197 | - # ... | |
| 168 | + # Do not build counts cube if we have already one in the observation | |
| 169 | + # container | |
| 198 | 170 | if self._skip_binning: |
| 199 | - cta_counts_cube = gammalib.GCTAEventCube(self._obs[0].events().clone()) | |
| 171 | + cta_counts_cube = gammalib.GCTAEventCube(self._obs[0].events()) | |
| 200 | 172 | |
| 201 | - # ... | |
| 173 | + # ... otherwise generate one now from the event list | |
| 202 | 174 | else: |
| 203 | 175 | |
| 204 | 176 | # Write header |
| 205 | 177 | if self._logTerse(): |
| 206 | - self._log("\n") | |
| 207 | - self._log.header1("Generate binned map (ctbin)") | |
| 178 | + self._log('\n') | |
| 179 | + self._log.header1('Generate binned map (ctbin)') | |
| 208 | 180 | |
| 209 | 181 | # Create countsmap |
| 210 | 182 | bin = ctools.ctbin(self._obs) |
| 211 | - bin["nxpix"].integer(self._nxpix) | |
| 212 | - bin["nypix"].integer(self._nypix) | |
| 213 | - bin["proj"].string(self._proj) | |
| 214 | - bin["coordsys"].string(self._coordsys) | |
| 215 | - bin["xref"].real(self._xref) | |
| 216 | - bin["yref"].real(self._yref) | |
| 217 | - bin["enumbins"].integer(self._enumbins) | |
| 218 | - bin["ebinalg"].string(self._ebinalg) | |
| 219 | - bin["emin"].real(self._emin) | |
| 220 | - bin["emax"].real(self._emax) | |
| 221 | - bin["binsz"].real(self._binsz) | |
| 222 | - bin["chatter"].integer(self._chatter) | |
| 223 | - bin["clobber"].boolean(self._clobber) | |
| 224 | - bin["debug"].boolean(self._debug) | |
| 183 | + bin['nxpix'] = self['nxpix'].integer() | |
| 184 | + bin['nypix'] = self['nypix'].integer() | |
| 185 | + bin['proj'] = self['proj'].string() | |
| 186 | + bin['coordsys'] = self['coordsys'].string() | |
| 187 | + bin['xref'] = self['xref'].real() | |
| 188 | + bin['yref'] = self['yref'].real() | |
| 189 | + bin['enumbins'] = self['enumbins'].integer() | |
| 190 | + bin['ebinalg'] = self['ebinalg'].string() | |
| 191 | + bin['emin'] = self['emin'].real() | |
| 192 | + bin['emax'] = self['emax'].real() | |
| 193 | + bin['binsz'] = self['binsz'].real() | |
| 194 | + bin['chatter'] = self['chatter'].integer() | |
| 195 | + bin['clobber'] = self['clobber'].boolean() | |
| 196 | + bin['debug'] = self['debug'].boolean() | |
| 225 | 197 | bin.run() |
| 226 | 198 | |
| 227 | 199 | # Retrieve counts cube |
| ... | ... | @@ -232,63 +204,51 @@ class csresmap(ctools.cscript): |
| 232 | 204 | |
| 233 | 205 | # Write header |
| 234 | 206 | if self._logTerse(): |
| 235 | - self._log("\n") | |
| 236 | - self._log.header1("Generate model map (ctmodel)") | |
| 207 | + self._log('\n') | |
| 208 | + self._log.header1('Generate model map (ctmodel)') | |
| 237 | 209 | |
| 238 | 210 | # Create model map |
| 239 | 211 | model = ctools.ctmodel(self._obs) |
| 240 | 212 | model.cube(cta_counts_cube) |
| 241 | - model["chatter"].integer(self._chatter) | |
| 242 | - model["clobber"].boolean(self._clobber) | |
| 243 | - model["debug"].boolean(self._debug) | |
| 244 | - model["edisp"].boolean(self._edisp) | |
| 213 | + model['chatter'] = self['chatter'].integer() | |
| 214 | + model['clobber'] = self['clobber'].boolean() | |
| 215 | + model['debug'] = self['debug'].boolean() | |
| 216 | + model['edisp'] = self['edisp'].boolean() | |
| 245 | 217 | model.run() |
| 246 | 218 | |
| 247 | 219 | # Get model map into GSkyMap object |
| 248 | 220 | modelmap = model.cube().counts().copy() |
| 249 | 221 | |
| 250 | - # Store counts map as residual map. Note that we need a | |
| 251 | - # special construct here to avoid memory leaks. This seems | |
| 252 | - # to be a SWIG feature as SWIG creates a new object when | |
| 253 | - # calling bin.cube() | |
| 254 | - #residualmap = bin.cube().counts() | |
| 222 | + # Store counts map as residual map. Note that we need a special | |
| 223 | + # construct here to avoid memory leaks. This seems to be a SWIG feature | |
| 224 | + # as SWIG creates a new object when calling bin.cube() | |
| 255 | 225 | self._resmap = countmap.copy() |
| 256 | 226 | self._resmap.stack_maps() |
| 257 | 227 | modelmap.stack_maps() |
| 258 | 228 | |
| 259 | - # Continue calculations depending on given algorithm | |
| 260 | - if self._algorithm == "SUB": | |
| 229 | + # Get residual map algorithm type | |
| 230 | + algorithm = self['algorithm'].string() | |
| 261 | 231 | |
| 262 | - # Subtract maps | |
| 232 | + # Subtract maps | |
| 233 | + if algorithm == 'SUB': | |
| 263 | 234 | self._resmap -= modelmap |
| 264 | 235 | |
| 265 | - elif self._algorithm == "SUBDIV": | |
| 266 | - | |
| 267 | - # Subtract and divide by model map | |
| 236 | + # Subtract and divide by model map | |
| 237 | + elif algorithm == 'SUBDIV': | |
| 268 | 238 | self._resmap -= modelmap |
| 269 | 239 | self._resmap /= modelmap |
| 270 | - #for pixel in modelmap: | |
| 271 | - # if pixel != 0.0: | |
| 272 | - # pixel = 1.0/pixel | |
| 273 | - #self._resmap *= modelmap | |
| 274 | 240 | |
| 275 | - elif self._algorithm == "SUBDIVSQRT": | |
| 276 | - | |
| 277 | - # subtract and divide by sqrt of model map | |
| 241 | + # Subtract and divide by sqrt of model map | |
| 242 | + elif algorithm == 'SUBDIVSQRT': | |
| 278 | 243 | self._resmap -= modelmap |
| 279 | 244 | self._resmap /= modelmap.sqrt() |
| 280 | - #for pixel in modelmap: | |
| 281 | - # if pixel != 0.0: | |
| 282 | - # pixel = 1.0/math.sqrt(pixel) | |
| 283 | - #self._resmap *= modelmap | |
| 284 | 245 | |
| 246 | + # Raise exception if algorithm is unknown | |
| 285 | 247 | else: |
| 286 | - | |
| 287 | - # Raise error if algorithm is unkown | |
| 288 | - raise TypeError("Algorithm \""+self._algorithm+"\" not known") | |
| 248 | + raise TypeError('Algorithm "'+algorithm+'" not known') | |
| 289 | 249 | |
| 290 | 250 | # Optionally publish map |
| 291 | - if self._publish: | |
| 251 | + if self['publish'].boolean(): | |
| 292 | 252 | self.publish() |
| 293 | 253 | |
| 294 | 254 | # Return |
| ... | ... | @@ -296,7 +256,7 @@ class csresmap(ctools.cscript): |
| 296 | 256 | |
| 297 | 257 | def execute(self): |
| 298 | 258 | """ |
| 299 | - Execute the script. | |
| 259 | + Execute the script | |
| 300 | 260 | """ |
| 301 | 261 | # Open logfile |
| 302 | 262 | self.logFileOpen() |
| ... | ... | @@ -315,55 +275,59 @@ class csresmap(ctools.cscript): |
| 315 | 275 | |
| 316 | 276 | def save(self): |
| 317 | 277 | """ |
| 318 | - Save residual map. | |
| 278 | + Save residual map | |
| 319 | 279 | """ |
| 320 | 280 | # Write header |
| 321 | 281 | if self._logTerse(): |
| 322 | - self._log("\n") | |
| 323 | - self._log.header1("Save residual map") | |
| 282 | + self._log('\n') | |
| 283 | + self._log.header1('Save residual map') | |
| 324 | 284 | |
| 325 | 285 | # Get outmap parameter |
| 326 | - outmap = self["outmap"].filename() | |
| 286 | + outmap = self['outmap'].filename() | |
| 327 | 287 | |
| 328 | 288 | # Continue only filename and residual map are valid |
| 329 | 289 | if self._resmap != None: |
| 330 | 290 | |
| 331 | 291 | # Log file name |
| 332 | 292 | if self._logTerse(): |
| 333 | - self._log(gammalib.parformat("Residual map file")) | |
| 293 | + self._log(gammalib.parformat('Residual map file')) | |
| 334 | 294 | self._log(outmap.url()) |
| 335 | - self._log("\n") | |
| 295 | + self._log('\n') | |
| 336 | 296 | |
| 337 | 297 | # Save residual map |
| 338 | - self._resmap.save(outmap, self._clobber) | |
| 298 | + self._resmap.save(outmap, self['clobber'].boolean()) | |
| 339 | 299 | |
| 340 | 300 | # Return |
| 341 | 301 | return |
| 342 | 302 | |
| 343 | - def publish(self, name=""): | |
| 303 | + def publish(self, name=''): | |
| 344 | 304 | """ |
| 345 | 305 | Publish residual map. |
| 346 | 306 | |
| 347 | - Kwargs: | |
| 348 | - name: Name of residual map. | |
| 307 | + Parameters | |
| 308 | + ---------- | |
| 309 | + name : str, optional | |
| 310 | + Name of residual map | |
| 349 | 311 | """ |
| 350 | 312 | # Write header |
| 351 | 313 | if self._logTerse(): |
| 352 | - self._log("\n") | |
| 353 | - self._log.header1("Publish residual map") | |
| 314 | + self._log('\n') | |
| 315 | + self._log.header1('Publish residual map') | |
| 354 | 316 | |
| 355 | 317 | # Continue only if residual map is valid |
| 356 | 318 | if self._resmap != None: |
| 357 | 319 | |
| 358 | 320 | # Set default name is user name is empty |
| 359 | 321 | if not name: |
| 360 | - user_name = self.name | |
| 322 | + user_name = self._name | |
| 361 | 323 | else: |
| 362 | 324 | user_name = name |
| 363 | 325 | |
| 364 | 326 | # Log map name |
| 365 | 327 | if self._logTerse(): |
| 366 | - self._log("Publish residual map \""+user_name+"\".\n") | |
| 328 | + self._log(gammalib.parformat('Residual map name')) | |
| 329 | + self._log(user_name) | |
| 330 | + self._log('\n') | |
| 367 | 331 | |
| 368 | 332 | # Publish map |
| 369 | 333 | self._resmap.publish(user_name) |
| ... | ... | @@ -373,10 +337,10 @@ class csresmap(ctools.cscript): |
| 373 | 337 | |
| 374 | 338 | def models(self, models): |
| 375 | 339 | """ |
| 376 | - Set model. | |
| 340 | + Set model | |
| 377 | 341 | """ |
| 378 | 342 | # Copy models |
| 379 | - self._obs.models(models.clone()) | |
| 343 | + self._obs.models(models) | |
| 380 | 344 | |
| 381 | 345 | # Return |
| 382 | 346 | return | ... | ... |
test/test_csresmap.py
| ... | ... | @@ -76,7 +76,7 @@ class Test(test): |
| 76 | 76 | ' emin=0.1 emax=100.0 enumbins=20'+ \ |
| 77 | 77 | ' nxpix=50 nypix=50 binsz=0.02'+ \ |
| 78 | 78 | ' coordsys="CEL" proj="CAR" xref=83.63 yref=22.01'+ \ |
| 79 | - ' algorithm="SUBDIV"'+ \ | |
| 79 | + ' algorithm="SUBDIVSQRT"'+ \ | |
| 80 | 80 | ' logfile="csresmap_cmd1.log" chatter=1' |
| 81 | 81 | |
| 82 | 82 | # Check if execution of wrong command fails |
| ... | ... | @@ -98,7 +98,7 @@ class Test(test): |
| 98 | 98 | ' emin=0.1 emax=100.0 enumbins=20'+ \ |
| 99 | 99 | ' nxpix=50 nypix=50 binsz=0.02'+ \ |
| 100 | 100 | ' coordsys="CEL" proj="CAR" xref=83.63 yref=22.01'+ \ |
| 101 | - ' algorithm="SUBDIV"'+ \ | |
| 101 | + ' algorithm="SUBDIVSQRT"'+ \ | |
| 102 | 102 | ' logfile="csresmap_cmd2.log" chatter=2' |
| 103 | 103 | |
| 104 | 104 | # Check if execution failed |
| ... | ... | @@ -130,7 +130,7 @@ class Test(test): |
| 130 | 130 | resmap['proj'] = 'CAR' |
| 131 | 131 | resmap['xref'] = 83.63 |
| 132 | 132 | resmap['yref'] = 22.01 |
| 133 | - resmap['algorithm'] = 'SUBDIV' | |
| 133 | + resmap['algorithm'] = 'SUB' | |
| 134 | 134 | resmap['logfile'] = 'csresmap_py1.log' |
| 135 | 135 | resmap['chatter'] = 2 |
| 136 | 136 | |
| ... | ... | @@ -157,6 +157,7 @@ class Test(test): |
| 157 | 157 | resmap['algorithm'] = 'SUBDIV' |
| 158 | 158 | resmap['logfile'] = 'csresmap_py2.log' |
| 159 | 159 | resmap['chatter'] = 3 |
| 160 | + resmap['publish'] = True | |
| 160 | 161 | |
| 161 | 162 | # Run csresmap script |
| 162 | 163 | resmap.execute() | ... | ... |