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""" 

2This file defines GalSimBase, which is a daughter of InstanceCatalog designed 

3to interface with GalSimInterpreter and generate images using GalSim. 

4 

5It also defines daughter classes of GalSimBase designed for specific 

6classes of astronomical objects: 

7 

8GalSimGalaxies 

9GalSimAgn 

10GalSimStars 

11""" 

12 

13from builtins import zip 

14from builtins import str 

15import numpy as np 

16import os 

17 

18import lsst.utils 

19from lsst.sims.utils import arcsecFromRadians 

20from lsst.sims.catalogs.definitions import InstanceCatalog 

21from lsst.sims.catalogs.decorators import cached 

22from lsst.sims.catUtils.mixins import (CameraCoords, AstrometryGalaxies, AstrometryStars, 

23 EBVmixin) 

24from lsst.sims.GalSimInterface import GalSimInterpreter, GalSimDetector, GalSimCelestialObject 

25from lsst.sims.GalSimInterface import GalSimCameraWrapper 

26from lsst.sims.GalSimInterface import make_galsim_detector 

27from lsst.sims.photUtils import (Sed, Bandpass, BandpassDict, 

28 PhotometricParameters) 

29from lsst.afw.cameraGeom import DetectorType 

30 

31__all__ = ["GalSimGalaxies", "GalSimAgn", "GalSimStars", "GalSimRandomWalk"] 

32 

33 

34def _is_null(argument): 

35 """ 

36 Return True if 'argument' is some null value 

37 (i.e. 'Null', None, nan). 

38 False otherwise. 

39 This is used by InstanceCatalog.write_catalog() to identify rows 

40 with null values in key columns. 

41 """ 

42 try: 

43 str_class = basestring 

44 except: 

45 str_class = str 

46 

47 if argument is None: 

48 return True 

49 elif isinstance(argument, str_class): 

50 if argument.strip().lower() == 'null': 

51 return True 

52 elif argument.strip().lower() == 'nan': 

53 return True 

54 elif argument.strip().lower() == 'none': 

55 return True 

56 elif np.isnan(argument): 

57 return True 

58 

59 return False 

60 

61 

62class GalSimBase(InstanceCatalog, CameraCoords): 

63 """ 

64 The catalog classes in this file use the InstanceCatalog infrastructure to construct 

65 FITS images for each detector-filter combination on a simulated camera. This is done by 

66 instantiating the class GalSimInterpreter. GalSimInterpreter is the class which 

67 actually generates the FITS images. As the GalSim InstanceCatalogs are iterated over, 

68 each object in the catalog is passed to the GalSimInterpeter, which adds the object 

69 to the appropriate FITS images. The user can then write the images to disk by calling 

70 the write_images method in the GalSim InstanceCatalog. 

71 

72 Objects are passed to the GalSimInterpreter by the get_fitsFiles getter function, which 

73 adds a column to the InstanceCatalog indicating which detectors' FITS files contain each 

74 object. 

75 

76 Note: because each GalSim InstanceCatalog has its own GalSimInterpreter, it means 

77 that each GalSimInterpreter will only draw FITS images containing one type of object 

78 (whatever type of object is contained in the GalSim InstanceCatalog). If the user 

79 wishes to generate FITS images containing multiple types of object, the method 

80 copyGalSimInterpreter allows the user to pass the GalSimInterpreter from one 

81 GalSim InstanceCatalog to another (so, the user could create a GalSim Instance 

82 Catalog of stars, generate that InstanceCatalog, then create a GalSim InstanceCatalog 

83 of galaxies, pass the GalSimInterpreter from the star catalog to this new catalog, 

84 and thus create FITS images that contain both stars and galaxies; see galSimCompoundGenerator.py 

85 in the examples/ directory of sims_catUtils for an example). 

86 

87 This class (GalSimBase) is the base class for all GalSim InstanceCatalogs. Daughter 

88 classes of this class need to behave like ordinary InstanceCatalog daughter classes 

89 with the following exceptions: 

90 

91 1) If they re-define column_outputs, they must be certain to include the column 

92 'fitsFiles.' The getter for this column (defined in this class) calls all of the 

93 GalSim image generation infrastructure 

94 

95 2) Daughter classes of this class must define a member variable galsim_type that is either 

96 'sersic' or 'pointSource'. This variable tells the GalSimInterpreter how to draw the 

97 object (to allow a different kind of image profile, define a new method in the GalSimInterpreter 

98 class similar to drawPoinSource and drawSersic) 

99 

100 3) The variables bandpass_names (a list of the form ['u', 'g', 'r', 'i', 'z', 'y']), 

101 bandpass_directory, and bandpass_root should be defined to tell the GalSim InstanceCatalog 

102 where to find the files defining the bandpasses to be used for these FITS files. 

103 The GalSim InstanceCatalog will look for bandpass files in files with the names 

104 

105 for bpn in bandpass_names: 

106 name = self.bandpass_directory+'/'+self.bandpass_root+'_'+bpn+'.dat' 

107 

108 one should also define the following member variables: 

109 

110 componentList is a list of files ins banpass_directory containing the response 

111 curves for the different components of the camera, e.g. 

112 ['detector.dat', 'm1.dat', 'm2.dat', 'm3.dat', 'lens1.dat', 'lens2.dat', 'lens3.dat'] 

113 

114 atomTransmissionName is the name of the file in bandpass_directory that contains the 

115 atmostpheric transmissivity, e.g. 'atmos_std.dat' 

116 

117 4) Telescope parameters such as exposure time, area, and gain are stored in the 

118 GalSim InstanceCatalog member variable photParams, which is an instantiation of 

119 the class PhotometricParameters defined in sims_photUtils. 

120 

121 Daughter classes of GalSimBase will generate both FITS images for all of the detectors/filters 

122 in their corresponding cameras and InstanceCatalogs listing all of the objects 

123 contained in those images. The catalog is written using the normal write_catalog() 

124 method provided for all InstanceClasses. The FITS files are drawn using the write_images() 

125 method that is unique to GalSim InstanceCatalogs. The FITS file will be named something like: 

126 

127 DetectorName_FilterName.fits 

128 

129 (a typical LSST fits file might be R_0_0_S_1_0_y.fits) 

130 

131 Note: If you call write_images() before iterating over the catalog (either by calling 

132 write_catalog() or using the iterator returned by InstanceCatalog.iter_catalog()), 

133 you will get empty or incomplete FITS files. Objects are only added to the GalSimInterpreter 

134 in the course of iterating over the InstanceCatalog. 

135 """ 

136 

137 seed = 42 

138 

139 # This is sort of a hack; it prevents findChipName in coordUtils from dying 

140 # if an object lands on multiple science chips. 

141 allow_multiple_chips = True 

142 

143 # There is no point in writing things to the InstanceCatalog that do not have SEDs and/or 

144 # do not land on any detectors 

145 cannot_be_null = ['sedFilepath'] 

146 

147 column_outputs = ['galSimType', 'uniqueId', 'raICRS', 'decICRS', 

148 'chipName', 'x_pupil', 'y_pupil', 'sedFilepath', 

149 'majorAxis', 'minorAxis', 'sindex', 'halfLightRadius', 

150 'npoints', 'positionAngle', 'fitsFiles'] 

151 

152 transformations = {'raICRS': np.degrees, 

153 'decICRS': np.degrees, 

154 'x_pupil': arcsecFromRadians, 

155 'y_pupil': arcsecFromRadians, 

156 'halfLightRadius': arcsecFromRadians} 

157 

158 default_formats = {'S': '%s', 'f': '%.9g', 'i': '%i'} 

159 

160 # This is used as the delimiter because the names of the detectors printed in the fitsFiles 

161 # column contain both ':' and ',' 

162 delimiter = '; ' 

163 

164 sedDir = lsst.utils.getPackageDir('sims_sed_library') 

165 

166 bandpassNames = None 

167 bandpassDir = os.path.join(lsst.utils.getPackageDir('throughputs'), 'baseline') 

168 bandpassRoot = 'filter_' 

169 componentList = ['detector.dat', 'm1.dat', 'm2.dat', 'm3.dat', 

170 'lens1.dat', 'lens2.dat', 'lens3.dat'] 

171 atmoTransmissionName = 'atmos_std.dat' 

172 

173 # allowed_chips is a list of the names of the detectors we actually want to draw. 

174 # If 'None', then all chips are drawn. 

175 allowed_chips = None 

176 

177 # This member variable will define a PSF to convolve with the sources. 

178 # See the classes PSFbase and DoubleGaussianPSF in 

179 # galSimUtilities.py for more information 

180 PSF = None 

181 

182 # This member variable can store a GalSim noise model instantiation 

183 # which will be applied to the FITS images when they are created 

184 noise_and_background = None 

185 

186 # Stores the gain and readnoise 

187 photParams = PhotometricParameters() 

188 

189 # This must be an instantiation of the GalSimCameraWrapper class defined in 

190 # galSimCameraWrapper.py 

191 _camera_wrapper = None 

192 

193 hasBeenInitialized = False 

194 

195 galSimInterpreter = None # the GalSimInterpreter instantiation for this catalog 

196 

197 totalDrawings = 0 

198 totalObjects = 0 

199 

200 @property 

201 def camera_wrapper(self): 

202 return self._camera_wrapper 

203 

204 @camera_wrapper.setter 

205 def camera_wrapper(self, val): 

206 self._camera_wrapper = val 

207 self.camera = val.camera 

208 

209 def _initializeGalSimCatalog(self): 

210 """ 

211 Initializes an empty list of objects that have already been drawn to FITS images. 

212 We do not want to accidentally draw an object twice. 

213 

214 Also initializes the GalSimInterpreter by calling self._initializeGalSimInterpreter() 

215 

216 Objects are stored based on their uniqueId values. 

217 """ 

218 self.objectHasBeenDrawn = set() 

219 self._initializeGalSimInterpreter() 

220 self.hasBeenInitialized = True 

221 

222 @cached 

223 def get_sedFilepath(self): 

224 """ 

225 Maps the name of the SED as stored in the database to the file stored in 

226 sims_sed_library 

227 """ 

228 # copied from the phoSim catalogs 

229 return np.array([self.specFileMap[k] if k in self.specFileMap else None 

230 for k in self.column_by_name('sedFilename')]) 

231 

232 def _calcSingleGalSimSed(self, sedName, zz, iAv, iRv, gAv, gRv, norm): 

233 """ 

234 correct the SED for redshift, dust, etc. Return an Sed object as defined in 

235 sims_photUtils/../../Sed.py 

236 """ 

237 if _is_null(sedName): 

238 return None 

239 sed = Sed() 

240 sed.readSED_flambda(os.path.join(self.sedDir, sedName)) 

241 imsimband = Bandpass() 

242 imsimband.imsimBandpass() 

243 # normalize the SED 

244 # Consulting the file sed.py in GalSim/galsim/ it appears that GalSim expects 

245 # its SEDs to ultimately be in units of ergs/nm so that, when called, they can 

246 # be converted to photons/nm (see the function __call__() and the assignment of 

247 # self._rest_photons in the __init__() of galsim's sed.py file). Thus, we need 

248 # to read in our SEDs, normalize them, and then multiply by the exposure time 

249 # and the effective area to get from ergs/s/cm^2/nm to ergs/nm. 

250 # 

251 # The gain parameter should convert between photons and ADU (so: it is the 

252 # traditional definition of "gain" -- electrons per ADU -- multiplied by the 

253 # quantum efficiency of the detector). Because we fold the quantum efficiency 

254 # of the detector into our total_[u,g,r,i,z,y].dat bandpass files 

255 # (see the readme in the THROUGHPUTS_DIR/baseline/), we only need to multiply 

256 # by the electrons per ADU gain. 

257 # 

258 # We will take these parameters from an instantiation of the PhotometricParameters 

259 # class (which can be reassigned by defining a daughter class of this class) 

260 # 

261 fNorm = sed.calcFluxNorm(norm, imsimband) 

262 sed.multiplyFluxNorm(fNorm) 

263 

264 # apply dust extinction (internal) 

265 if iAv != 0.0 and iRv != 0.0: 

266 a_int, b_int = sed.setupCCM_ab() 

267 sed.addDust(a_int, b_int, A_v=iAv, R_v=iRv) 

268 

269 # 22 June 2015 

270 # apply redshift; there is no need to apply the distance modulus from 

271 # sims/photUtils/CosmologyWrapper; magNorm takes that into account 

272 # however, magNorm does not take into account cosmological dimming 

273 if zz != 0.0: 

274 sed.redshiftSED(zz, dimming=True) 

275 

276 # apply dust extinction (galactic) 

277 if gAv != 0.0 and gRv != 0.0: 

278 a_int, b_int = sed.setupCCM_ab() 

279 sed.addDust(a_int, b_int, A_v=gAv, R_v=gRv) 

280 return sed 

281 

282 def _calculateGalSimSeds(self): 

283 """ 

284 Apply any physical corrections to the objects' SEDS (redshift them, apply dust, etc.). 

285 

286 Return a generator that serves up the Sed objects in order. 

287 """ 

288 actualSEDnames = self.column_by_name('sedFilepath') 

289 redshift = self.column_by_name('redshift') 

290 internalAv = self.column_by_name('internalAv') 

291 internalRv = self.column_by_name('internalRv') 

292 galacticAv = self.column_by_name('galacticAv') 

293 galacticRv = self.column_by_name('galacticRv') 

294 magNorm = self.column_by_name('magNorm') 

295 

296 return (self._calcSingleGalSimSed(*args) for args in 

297 zip(actualSEDnames, redshift, internalAv, internalRv, 

298 galacticAv, galacticRv, magNorm)) 

299 

300 @cached 

301 def get_fitsFiles(self, checkpoint_file=None, nobj_checkpoint=1000): 

302 """ 

303 This getter returns a column listing the names of the detectors whose corresponding 

304 FITS files contain the object in question. The detector names will be separated by a '//' 

305 

306 This getter also passes objects to the GalSimInterpreter to actually draw the FITS 

307 images. 

308 

309 WARNING: do not include 'fitsFiles' in the cannot_be_null list of non-null columns. 

310 If you do that, this method will be called several times by the catalog, as it 

311 attempts to determine which rows are actually in the catalog. That will cause 

312 your images to have too much flux in them. 

313 """ 

314 if self.bandpassNames is None: 

315 if isinstance(self.obs_metadata.bandpass, list): 

316 self.bandpassNames = [self.obs_metadata.bandpass] 

317 else: 

318 self.bandpassNames = self.obs_metadata.bandpass 

319 

320 objectNames = self.column_by_name('uniqueId') 

321 xPupil = self.column_by_name('x_pupil') 

322 yPupil = self.column_by_name('y_pupil') 

323 halfLight = self.column_by_name('halfLightRadius') 

324 minorAxis = self.column_by_name('minorAxis') 

325 majorAxis = self.column_by_name('majorAxis') 

326 positionAngle = self.column_by_name('positionAngle') 

327 sindex = self.column_by_name('sindex') 

328 npoints = self.column_by_name('npoints') 

329 gamma1 = self.column_by_name('gamma1') 

330 gamma2 = self.column_by_name('gamma2') 

331 kappa = self.column_by_name('kappa') 

332 

333 sedList = self._calculateGalSimSeds() 

334 

335 if self.hasBeenInitialized is False and len(objectNames) > 0: 

336 # This needs to be here in case, instead of writing the whole catalog with write_catalog(), 

337 # the user wishes to iterate through the catalog with InstanceCatalog.iter_catalog(), 

338 # which will not call write_header() 

339 self._initializeGalSimCatalog() 

340 if not hasattr(self, 'bandpassDict'): 

341 raise RuntimeError('ran initializeGalSimCatalog but do not have bandpassDict') 

342 self.galSimInterpreter.checkpoint_file = checkpoint_file 

343 self.galSimInterpreter.nobj_checkpoint = nobj_checkpoint 

344 self.galSimInterpreter.restore_checkpoint(self._camera_wrapper, 

345 self.photParams, 

346 self.obs_metadata, 

347 epoch=self.db_obj.epoch) 

348 

349 output = [] 

350 for (name, xp, yp, hlr, minor, major, pa, ss, sn, npo, gam1, gam2, kap) in \ 

351 zip(objectNames, xPupil, yPupil, halfLight, 

352 minorAxis, majorAxis, positionAngle, sedList, sindex, npoints, 

353 gamma1, gamma2, kappa): 

354 

355 if name in self.objectHasBeenDrawn: 

356 raise RuntimeError('Trying to draw %s more than once ' % str(name)) 

357 elif ss is None: 

358 raise RuntimeError('Trying to draw an object with SED == None') 

359 else: 

360 

361 self.objectHasBeenDrawn.add(name) 

362 

363 if name not in self.galSimInterpreter.drawn_objects: 

364 

365 gsObj = GalSimCelestialObject(self.galsim_type, xp, yp, 

366 hlr, minor, major, pa, sn, 

367 ss, self.bandpassDict, self.photParams, 

368 npo, None, None, None, 

369 gam1, gam2, kap, uniqueId=name) 

370 

371 # actually draw the object 

372 detectorsString = self.galSimInterpreter.drawObject(gsObj) 

373 else: 

374 # For objects that have already been drawn in the 

375 # checkpointed data, use a blank string. 

376 detectorsString = '' 

377 

378 output.append(detectorsString) 

379 

380 # Force checkpoint at the end (if a checkpoint file has been specified). 

381 if self.galSimInterpreter is not None: 

382 self.galSimInterpreter.write_checkpoint(force=True) 

383 return np.array(output) 

384 

385 def setPSF(self, PSF): 

386 """ 

387 Set the PSF of this GalSimCatalog after instantiation. 

388 

389 @param [in] PSF is an instantiation of a GalSimPSF class. 

390 """ 

391 self.PSF = PSF 

392 if self.galSimInterpreter is not None: 

393 self.galSimInterpreter.setPSF(PSF=PSF) 

394 

395 def copyGalSimInterpreter(self, otherCatalog): 

396 """ 

397 Copy the camera, GalSimInterpreter, from another GalSim InstanceCatalog 

398 so that multiple types of object (stars, AGN, galaxy bulges, galaxy disks, etc.) 

399 can be drawn on the same FITS files. 

400 

401 @param [in] otherCatalog is another GalSim InstanceCatalog that already has 

402 an initialized GalSimInterpreter 

403 

404 See galSimCompoundGenerator.py in the examples/ directory of sims_catUtils for 

405 an example of how this is used. 

406 """ 

407 self.camera_wrapper = otherCatalog.camera_wrapper 

408 self.photParams = otherCatalog.photParams 

409 self.PSF = otherCatalog.PSF 

410 self.noise_and_background = otherCatalog.noise_and_background 

411 if otherCatalog.hasBeenInitialized: 

412 self.bandpassDict = otherCatalog.bandpassDict 

413 self.galSimInterpreter = otherCatalog.galSimInterpreter 

414 

415 def _initializeGalSimInterpreter(self): 

416 """ 

417 This method creates the GalSimInterpreter (if it is None) 

418 

419 This method reads in all of the data about the camera and pass it into 

420 the GalSimInterpreter. 

421 

422 This method calls _getBandpasses to construct the paths to 

423 the files containing the bandpass data. 

424 """ 

425 

426 if not isinstance(self.camera_wrapper, GalSimCameraWrapper): 

427 raise RuntimeError("GalSimCatalog.camera_wrapper must be an instantiation of " 

428 "GalSimCameraWrapper or one of its daughter classes\n" 

429 "It is actually of type %s" % str(type(self.camera_wrapper))) 

430 

431 if self.galSimInterpreter is None: 

432 

433 # This list will contain instantiations of the GalSimDetector class 

434 # (see galSimInterpreter.py), which stores detector information in a way 

435 # that the GalSimInterpreter will understand 

436 detectors = [] 

437 

438 for dd in self.camera_wrapper.camera: 

439 if dd.getType() == DetectorType.WAVEFRONT or dd.getType() == DetectorType.GUIDER: 

440 # This package does not yet handle the 90-degree rotation 

441 # in WCS that occurs for wavefront or guide sensors 

442 continue 

443 

444 if self.allowed_chips is None or dd.getName() in self.allowed_chips: 

445 detectors.append(make_galsim_detector(self.camera_wrapper, dd.getName(), 

446 self.photParams, self.obs_metadata, 

447 epoch=self.db_obj.epoch)) 

448 

449 if not hasattr(self, 'bandpassDict'): 

450 if self.noise_and_background is not None: 

451 if self.obs_metadata.m5 is None: 

452 raise RuntimeError('WARNING in GalSimCatalog; you did not specify m5 in your ' 

453 'obs_metadata. m5 is required in order to ' 

454 'add noise to your images') 

455 

456 for name in self.bandpassNames: 

457 if name not in self.obs_metadata.m5: 

458 raise RuntimeError('WARNING in GalSimCatalog; your obs_metadata does not have ' + 

459 'm5 values for all of your bandpasses \n' + 

460 'bandpass has: %s \n' % self.bandpassNames.__repr__() + 

461 'm5 has: %s ' % list(self.obs_metadata.m5.keys()).__repr__()) 

462 

463 if self.obs_metadata.seeing is None: 

464 raise RuntimeError('WARNING in GalSimCatalog; you did not specify seeing in your ' 

465 'obs_metadata. seeing is required in order to add ' 

466 'noise to your images') 

467 

468 for name in self.bandpassNames: 

469 if name not in self.obs_metadata.seeing: 

470 raise RuntimeError('WARNING in GalSimCatalog; your obs_metadata does not have ' + 

471 'seeing values for all of your bandpasses \n' + 

472 'bandpass has: %s \n' % self.bandpassNames.__repr__() + 

473 'seeing has: %s ' % list(self.obs_metadata.seeing.keys()).__repr__()) 

474 

475 (self.bandpassDict, 

476 hardwareDict) = BandpassDict.loadBandpassesFromFiles(bandpassNames=self.bandpassNames, 

477 filedir=self.bandpassDir, 

478 bandpassRoot=self.bandpassRoot, 

479 componentList=self.componentList, 

480 atmoTransmission=os.path.join(self.bandpassDir, 

481 self.atmoTransmissionName)) 

482 

483 self.galSimInterpreter = GalSimInterpreter(obs_metadata=self.obs_metadata, 

484 epoch=self.db_obj.epoch, 

485 detectors=detectors, 

486 bandpassDict=self.bandpassDict, 

487 noiseWrapper=self.noise_and_background, 

488 seed=self.seed) 

489 

490 self.galSimInterpreter.setPSF(PSF=self.PSF) 

491 

492 

493 

494 def write_images(self, nameRoot=None): 

495 """ 

496 Writes the FITS images associated with this InstanceCatalog. 

497 

498 Cannot be called before write_catalog is called. 

499 

500 @param [in] nameRoot is an optional string prepended to the names 

501 of the FITS images. The FITS images will be named 

502 

503 @param [out] namesWritten is a list of the names of the FITS files generated 

504 

505 nameRoot_DetectorName_FilterName.fits 

506 

507 (e.g. myImages_R_0_0_S_1_1_y.fits for an LSST-like camera with 

508 nameRoot = 'myImages') 

509 """ 

510 namesWritten = self.galSimInterpreter.writeImages(nameRoot=nameRoot) 

511 

512 return namesWritten 

513 

514 

515class GalSimGalaxies(GalSimBase, AstrometryGalaxies, EBVmixin): 

516 """ 

517 This is a GalSimCatalog class for galaxy components (i.e. objects that are shaped 

518 like Sersic profiles). 

519 

520 See the docstring in GalSimBase for explanation of how this class should be used. 

521 """ 

522 

523 catalog_type = 'galsim_galaxy' 

524 galsim_type = 'sersic' 

525 default_columns = [('galacticAv', 0.1, float), 

526 ('galacticRv', 3.1, float), 

527 ('galSimType', 'sersic', str, 6), 

528 ('npoints', 0, int), 

529 ('gamma1', 0.0, float), 

530 ('gamma2', 0.0, float), 

531 ('kappa', 0.0, float)] 

532 

533class GalSimRandomWalk(GalSimBase, AstrometryGalaxies, EBVmixin): 

534 """ 

535 This is a GalSimCatalog class for galaxy components (i.e. objects that are shaped 

536 like Sersic profiles). 

537 

538 See the docstring in GalSimBase for explanation of how this class should be used. 

539 """ 

540 

541 catalog_type = 'galsim_random_walk' 

542 galsim_type = 'RandomWalk' 

543 default_columns = [('galacticAv', 0.1, float), 

544 ('galacticRv', 3.1, float), 

545 ('galSimType', 'RandomWalk', str, 10), 

546 ('sindex', 0.0, float), 

547 ('gamma1', 0.0, float), 

548 ('gamma2', 0.0, float), 

549 ('kappa', 0.0, float)] 

550 

551class GalSimAgn(GalSimBase, AstrometryGalaxies, EBVmixin): 

552 """ 

553 This is a GalSimCatalog class for AGN. 

554 

555 See the docstring in GalSimBase for explanation of how this class should be used. 

556 """ 

557 catalog_type = 'galsim_agn' 

558 galsim_type = 'pointSource' 

559 default_columns = [('galacticAv', 0.1, float), 

560 ('galacticRv', 3.1, float), 

561 ('galSimType', 'pointSource', str, 11), 

562 ('majorAxis', 0.0, float), 

563 ('minorAxis', 0.0, float), 

564 ('sindex', 0.0, float), 

565 ('npoints', 0, int), 

566 ('positionAngle', 0.0, float), 

567 ('halfLightRadius', 0.0, float), 

568 ('internalAv', 0.0, float), 

569 ('internalRv', 0.0, float), 

570 ('gamma1', 0.0, float), 

571 ('gamma2', 0.0, float), 

572 ('kappa', 0.0, float)] 

573 

574 

575class GalSimStars(GalSimBase, AstrometryStars): 

576 """ 

577 This is a GalSimCatalog class for stars. 

578 

579 See the docstring in GalSimBase for explanation of how this class should be used. 

580 """ 

581 catalog_type = 'galsim_stars' 

582 galsim_type = 'pointSource' 

583 default_columns = [('galacticAv', 0.1, float), 

584 ('galacticRv', 3.1, float), 

585 ('galSimType', 'pointSource', str, 11), 

586 ('internalAv', 0.0, float), 

587 ('internalRv', 0.0, float), 

588 ('redshift', 0.0, float), 

589 ('majorAxis', 0.0, float), 

590 ('minorAxis', 0.0, float), 

591 ('sindex', 0.0, float), 

592 ('npoints', 0, int), 

593 ('positionAngle', 0.0, float), 

594 ('halfLightRadius', 0.0, float), 

595 ('gamma1', 0.0, float), 

596 ('gamma2', 0.0, float), 

597 ('kappa', 0.0, float)]