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

1from sqlalchemy import text 

2from lsst.utils import getPackageDir 

3import lsst.pex.config as pexConfig 

4from lsst.sims.utils import htmModule as htm 

5from lsst.sims.catalogs.db import CatalogDBObject, ChunkIterator 

6 

7__all__ = ["UWStarCatalogObj"] 

8 

9 

10class UWStarCatalogConfig(pexConfig.Config): 

11 host = pexConfig.Field( 

12 dtype = str, 

13 doc = "Name of the host", 

14 default = "localhost", 

15 ) 

16 port = pexConfig.Field( 

17 dtype = str, 

18 doc = "Port number of database", 

19 default = "1433", 

20 ) 

21 database = pexConfig.Field( 

22 dtype = str, 

23 doc = "Name of database. For 'sqlite', the filename is the database name", 

24 default = "LSST", 

25 ) 

26 driver = pexConfig.Field( 

27 dtype = str, 

28 doc = "Name of the database backend. Takes format of dialect+driver ", 

29 default = "mssql+pymssql", 

30 ) 

31 

32 

33class _HiddenStarCatalogObj(CatalogDBObject): 

34 

35 objid = 'hiddenstar' 

36 tableid = None 

37 idColKey = 'id' 

38 raColName = 'ra' 

39 decColName = 'decl' 

40 objectTypeId = 4 

41 

42 columns = [('id','simobjid', int), 

43 ('raJ2000', 'ra*PI()/180.'), 

44 ('decJ2000', 'decl*PI()/180.'), 

45 ('glon', 'gal_l*PI()/180.'), 

46 ('glat', 'gal_b*PI()/180.'), 

47 ('magNorm', '(-2.5*log(flux_scale)/log(10.)) - 18.402732642'), 

48 ('properMotionRa', '(mura/(1000.*3600.))*PI()/180.'), 

49 ('properMotionDec', '(mudecl/(1000.*3600.))*PI()/180.'), 

50 ('parallax', 'parallax*PI()/648000000.'), 

51 ('galacticAv', 'CONVERT(float, ebv*3.1)'), 

52 ('radialVelocity', 'vrad'), 

53 ('variabilityParameters', 'varParamStr', str, 256), 

54 ('sedFilename', 'sedfilename', str, 40)] 

55 

56 

57class UWStarChunkIterator(ChunkIterator): 

58 

59 _partition_lim = ((0,11000000000000,8700000000000), 

60 (11000000000000, 11600000000000, 11000000000000), 

61 (11600000000000, 11800000000000, 11600000000000), 

62 (11800000000000, 12000000000000, 11800000000000), 

63 (12000000000000, 12200000000000, 12000000000000), 

64 (12200000000000, 12500000000000, 12200000000000), 

65 (12500000000000, 14000000000000, 12500000000000), 

66 (14000000000000, 100000000000000000000, 14000000000000)) 

67 

68 def __init__(self, dbobj, colnames, obs_metadata, chunk_size, constraint, 

69 database, host, port, driver): 

70 """ 

71 Parameters 

72 ---------- 

73 dbobj -- a CatalogDBObject connected to the 'galaxies' table on fatboy 

74 

75 colnames -- a list of the columns to query 

76 

77 chunk_size -- size of chunks to return 

78 

79 constraint -- a string specifying a SQL 'WHERE' clause 

80 

81 database -- the name of the database to connect to 

82 

83 host -- the name of the host to connect to 

84 

85 port -- the port to connect to 

86 

87 driver -- the sqlalchemy driver to use 

88 """ 

89 self.database = database 

90 self.host = host 

91 self.port = port 

92 self.driver = driver 

93 

94 self.arbitrarySQL = False 

95 self._chunk_size = chunk_size 

96 self._obs_metadata = obs_metadata 

97 self._constraint = constraint 

98 self._colnames = colnames 

99 

100 half_space = htm.halfSpaceFromRaDec(obs_metadata.pointingRA, 

101 obs_metadata.pointingDec, 

102 obs_metadata.boundLength) 

103 

104 self._trixel_search_level = 12 

105 self._trixel_bounds = half_space.findAllTrixels(self._trixel_search_level) 

106 

107 self._tables_to_query = set() 

108 self._tables_to_query.add('starsRRLy') 

109 self._tables_to_query.add('starsWD') 

110 where_clause = '(' 

111 global_min_21 = None 

112 global_max_21 = None 

113 for bound in self._trixel_bounds: 

114 min_21 = bound[0] << 2*(21-self._trixel_search_level) 

115 max_21 = (bound[1]+1) << 2*(21-self._trixel_search_level) 

116 if global_min_21 is None or min_21<global_min_21: 

117 global_min_21 = min_21 

118 if global_max_21 is None or max_21>global_max_21: 

119 global_max_21 = max_21 

120 

121 if where_clause != '(': 

122 where_clause += ' OR ' 

123 

124 if min_21 == max_21: 

125 where_clause += 'htmid==%d' % min_21 

126 else: 

127 where_clause += '(htmid>=%d AND htmid<=%d)' % (min_21, max_21) 

128 

129 for part in self._partition_lim: 

130 part_name = 'stars_partition_%d' % part[2] 

131 if min_21>=part[0] and min_21<part[1]: 

132 self._tables_to_query.add(part_name) 

133 elif max_21>=part[0] and max_21<part[1]: 

134 self._tables_to_query.add(part_name) 

135 elif min_21<=part[0] and max_21>part[1]: 

136 self._tables_to_query.add(part_name) 

137 

138 where_clause += ')' 

139 self._htmid_where_clause = '(htmid>=%d AND htmid<=%d AND ' % (global_min_21, global_max_21) 

140 self._htmid_where_clause += where_clause 

141 self._htmid_where_clause += ')' 

142 

143 self._active_query = None 

144 

145 def _load_next_star_db(self, colnames): 

146 table_name = self._tables_to_query.pop() 

147 db = _HiddenStarCatalogObj(table=table_name, 

148 database=self.database, 

149 host=self.host, 

150 port=self.port, 

151 driver=self.driver) 

152 self.dbobj = db 

153 column_query = db._get_column_query(colnames) 

154 column_query = column_query.filter(text(self._htmid_where_clause)) 

155 if self._constraint is not None: 

156 column_query = column_query.filter(text(self._constraint)) 

157 exec_query = db.connection.session.execute(column_query) 

158 return exec_query 

159 

160 def __next__(self): 

161 

162 if self._active_query is None or self._active_query.closed: 

163 if len(self._tables_to_query) == 0: 

164 raise StopIteration 

165 self._active_query = self._load_next_star_db(self._colnames) 

166 

167 if self._chunk_size is None: 

168 chunk = self._active_query.fetchall() 

169 elif self._chunk_size is not None: 

170 chunk = self._active_query.fetchmany(self._chunk_size) 

171 if len(chunk) == 0: 

172 self._active_query.close() 

173 return self.__next__() 

174 

175 return self._postprocess_results(chunk) 

176 

177 

178class UWStarCatalogObj(CatalogDBObject): 

179 

180 config = UWStarCatalogConfig() 

181 

182 database = config.database 

183 host = config.host 

184 port = config.port 

185 driver = config.driver 

186 

187 idColKey = 'id' 

188 objid = 'epycStarBase' 

189 tableid = 'stars_partition_8700000000000' # just a placeholder 

190 

191 columns = [('id','simobjid', int), 

192 ('raJ2000', 'ra*PI()/180.'), 

193 ('decJ2000', 'decl*PI()/180.'), 

194 ('glon', 'gal_l*PI()/180.'), 

195 ('glat', 'gal_b*PI()/180.'), 

196 ('magNorm', '(-2.5*log(flux_scale)/log(10.)) - 18.402732642'), 

197 ('properMotionRa', '(mura/(1000.*3600.))*PI()/180.'), 

198 ('properMotionDec', '(mudecl/(1000.*3600.))*PI()/180.'), 

199 ('parallax', 'parallax*PI()/648000000.'), 

200 ('galacticAv', 'CONVERT(float, ebv*3.1)'), 

201 ('radialVelocity', 'vrad'), 

202 ('variabilityParameters', 'varParamStr', str, 256), 

203 ('sedFilename', 'sedfilename', str, 40)] 

204 

205 def get_table(self): 

206 """ 

207 We don't actually want this to do anything, since this CatalogDBObject 

208 does its own search over all of the available star tables 

209 """ 

210 pass 

211 

212 def query_columns(self, colnames=None, chunk_size=None, 

213 obs_metadata=None, constraint=None, 

214 limit=None): 

215 

216 if obs_metadata.boundType != 'circle': 

217 raise RuntimeError("Cannot use boundType %s in this catalog; only 'circle'" 

218 % str(obs_metadata.boundType)) 

219 

220 return UWStarChunkIterator(self, colnames, obs_metadata, chunk_size, 

221 constraint, 

222 self.database, 

223 self.host, 

224 self.port, 

225 self.driver)