File | /wise/base/deliv/dev/lib/perl/WISE/DB/FrameIndex.pm | Statements Executed | 2122 | Total Time | 0.0138030000000001 seconds |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine | |
---|---|---|---|---|---|---|
1 | 1 | 1 | 0.00469 | 0.27702 | WISE::DB::FrameIndex:: | _neighbor_hp |
1 | 1 | 1 | 0.00421 | 0.00421 | WISE::DB::FrameIndex:: | _optimize_in_clause |
1 | 1 | 1 | 0.00174 | 0.28391 | WISE::DB::FrameIndex:: | search |
1 | 1 | 1 | 0.00017 | 0.00017 | WISE::DB::FrameIndex:: | _prune_args |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | BEGIN |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | _check_action |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | _check_type |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | _utcs_params |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | add |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | add_frame |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | add_frameset |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | add_scan |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | copy |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | create |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | disconnect |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | frame |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | frameset |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | remove |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | remove_frame |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | remove_frameset |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | remove_scan |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | replace |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | scan |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | search_coord |
0 | 0 | 0 | 0 | 0 | WISE::DB::FrameIndex:: | search_utcs |
Line | Stmts. | Exclusive Time | Avg. | Code |
---|---|---|---|---|
1 | package WISE::DB::FrameIndex; | |||
2 | # $Id: FrameIndex.pm 7412 2010-02-20 01:58:56Z heidi $ | |||
3 | ||||
4 | 1 | 0 | 0 | our ($VERSION,$ID); |
5 | ||||
6 | 1 | 0 | 0 | $VERSION = 1.56; |
7 | 1 | 1.0e-6 | 1.0e-6 | $ID = '$Id: FrameIndex.pm 7412 2010-02-20 01:58:56Z heidi $'; |
8 | ||||
9 | 3 | 3.3e-5 | 1.1e-5 | use strict; # spent 12µs making 1 call to strict::import |
10 | 3 | 3.4e-5 | 1.1e-5 | use Carp; # spent 59µs making 1 call to Exporter::import |
11 | 3 | 6.9e-5 | 2.3e-5 | use base qw/DBIx::Class::Schema DBIx::Class::ResultSet/; # spent 61.5ms making 1 call to base::import |
12 | ||||
13 | ||||
14 | ||||
15 | =head1 NAME | |||
16 | ||||
17 | WISE::DB::FrameIndex - Frame Index and Operations Database for WISE | |||
18 | ||||
19 | =head1 SYNOPSIS | |||
20 | ||||
21 | use WISE::DB::FrameIndex; | |||
22 | ||||
23 | my $db = WISE::DB::FrameIndex->create( dbname => "dbi:SQLite:mytestdb" ); | |||
24 | ||||
25 | $db->add( 'scan', { scan => '00123a', | |||
26 | delivery => '454545'} ); | |||
27 | ||||
28 | my $frameset = $db->find( { scan => '00123a', | |||
29 | frame => 30 } ); | |||
30 | ||||
31 | $frameset->update( { pipe_status => 9 } ); | |||
32 | ||||
33 | =cut | |||
34 | ||||
35 | ||||
36 | 1 | 1.9e-5 | 1.9e-5 | __PACKAGE__->load_classes( { 'WISE::DB::FrameIndex' => [ qw/ Scan Frame HouseKeeping MissionPlan Tile / ] } ); # spent 73.7ms making 1 call to DBIx::Class::Schema::load_classes |
37 | ||||
38 | 3 | 0.00207 | 0.00069 | use WISE::CHealPix; # spent 40µs making 1 call to Exporter::import |
39 | ||||
40 | =head1 DESCRIPTION | |||
41 | ||||
42 | WISE::DB::FrameIndex provides basic create, add, remove, update functionality for the WISE operations | |||
43 | database. Packages within the WISE::DB::FrameIndex namespace utilize L<DBIx::Class> to provide an | |||
44 | object mapping to the backend relational database. The backend was prototyped with | |||
45 | SQLite. | |||
46 | ||||
47 | =cut | |||
48 | ||||
49 | ######################################################################################## | |||
50 | ######################################################################################## | |||
51 | ||||
52 | # utility methods for this class. not for outside use | |||
53 | ||||
54 | # TODO need something to check whether the passed in column args | |||
55 | # match what we have in our schema. or, equivalently, an exception class for DBIx::Class | |||
56 | # to use in such a case | |||
57 | ||||
58 | # get rid of everything in arguments hash that isn't a defined column in the schema | |||
59 | # TODO, base this on the defined columns | |||
60 | # spent 174µs within WISE::DB::FrameIndex::_prune_args which was called
# once (174µs+0) by WISE::DB::FrameIndex::search at line 483 | |||
61 | 3 | 1.3e-5 | 4.3e-6 | my $self = shift; |
62 | my @prunes = qw / ra dec radius utcs_start utcs_stop utcs_span num_frames/ ; | |||
63 | foreach my $p (@prunes) { | |||
64 | 34 | 0.00014 | 4.1e-6 | if( grep {/^$p$/} keys %{$_[0]} ) { |
65 | delete $_[0]->{$p}; | |||
66 | } | |||
67 | } | |||
68 | } | |||
69 | ||||
70 | ######################################################################################## | |||
71 | ######################################################################################## | |||
72 | ||||
73 | =head1 METHODS | |||
74 | ||||
75 | =head2 Database Utility Routines | |||
76 | ||||
77 | =over 4 | |||
78 | ||||
79 | =item create() | |||
80 | ||||
81 | ||||
82 | my $db = WISE::DB::FrameIndex->create( dbname => 'dbi:SQLite:testdb'); | |||
83 | ||||
84 | Takes a database name with included driver and engine specification expected by L<DBIx::Class>. | |||
85 | Uses SQL::Abstract to deploy the schema defined by packages in WISE::DB::FrameIndex namespace. Also sets up | |||
86 | the Healpix spatial tiling and initializes the tiling table with Healpix parameters. | |||
87 | ||||
88 | The tiling is currently hardcoded. In the future it will be configurable via arguments to create(). | |||
89 | ||||
90 | =cut | |||
91 | ||||
92 | sub create { | |||
93 | my $class = shift; | |||
94 | my %args = @_; | |||
95 | ||||
96 | # TODO: allow arguments to giving tiling | |||
97 | ||||
98 | my $schema = WISE::DB::FrameIndex->connect($args{dbname}); | |||
99 | if(defined $schema) { | |||
100 | $schema->deploy; | |||
101 | my $nside = WISE::CHealPix::side2nsides_deg((47/60) - 2*(4/60)); | |||
102 | $schema->resultset('Tile')->create( { side => (47/60), | |||
103 | overlap => (4/60), | |||
104 | dist => (47/60) - 2*(4/60), | |||
105 | nside => $nside, | |||
106 | npix => WISE::CHealPix::nside2npix($nside), } ); | |||
107 | } else { | |||
108 | carp __PACKAGE__." create: Couldn't connect to database (name=$args{dbname})\n"; | |||
109 | } | |||
110 | return $schema; | |||
111 | } | |||
112 | ||||
113 | =item copy() | |||
114 | ||||
115 | Stub only, not implemented | |||
116 | ||||
117 | =cut | |||
118 | ||||
119 | sub copy { | |||
120 | #my $db = shift; # this is DBIx::Class::Schema object | |||
121 | my $targetfile = shift; | |||
122 | #$new = $db->clone; | |||
123 | # TODO | |||
124 | } | |||
125 | ||||
126 | =item replace() | |||
127 | ||||
128 | Stub only, not implemented | |||
129 | ||||
130 | =cut | |||
131 | ||||
132 | sub replace { | |||
133 | ||||
134 | } | |||
135 | ||||
136 | =item disconnect() | |||
137 | ||||
138 | $db->disconnect; | |||
139 | ||||
140 | Disconnect from the database. This is a convenience routine which generally should not be called, | |||
141 | as the database will disconnect on object destruction (usually at scope exit). Note DBIx::Class will | |||
142 | take care of rolling back transactions (as long as autocommit => 1). | |||
143 | ||||
144 | =back | |||
145 | ||||
146 | =cut | |||
147 | ||||
148 | sub disconnect { | |||
149 | my $db = shift; | |||
150 | $db->storage->disconnect; | |||
151 | } | |||
152 | ||||
153 | ||||
154 | ######################################################################################## | |||
155 | ######################################################################################## | |||
156 | ||||
157 | # these subroutines implement a generic interface for adding and removing. | |||
158 | # the specific routines ('add_frameset', 'remove_scan, etc) are defined below | |||
159 | ||||
160 | 1 | 3.0e-6 | 3.0e-6 | my @types_ok = qw/ frame frameset scan /; |
161 | 1 | 2.0e-6 | 2.0e-6 | my @actions_ok = qw/ add remove search /; |
162 | ||||
163 | sub _check_type { | |||
164 | my ($self, $type) = @_; | |||
165 | return grep {/$type/} @types_ok; | |||
166 | } | |||
167 | ||||
168 | sub _check_action { | |||
169 | my ($self, $action) = @_; | |||
170 | return grep {/$action/} @actions_ok; | |||
171 | } | |||
172 | ||||
173 | =head2 Adding Data | |||
174 | ||||
175 | =over 4 | |||
176 | ||||
177 | =item add() | |||
178 | ||||
179 | $db->add( I<type>, { I<column values> } ); | |||
180 | ||||
181 | $db->add( 'scan', { scan => '00123c', delivery => '454545', num_frames => 30 } ); | |||
182 | $db->add( 'frame', { scan => '00456d', delivery => '454545', frame => '098', band => 1, | |||
183 | l0_file => 'testframe', scan_end => 0, ra_raw => 15.0, dec_raw => 45.0, | |||
184 | utcs => 1, } ); | |||
185 | ||||
186 | Valid types are I<frame>, I<frameset>, and I<scan>. When adding a scan, the num_frames | |||
187 | parameter can be given to insert a non-standard size scan; by default, adding | |||
188 | a scan means inserting 250 framesets. | |||
189 | ||||
190 | =back | |||
191 | ||||
192 | =cut | |||
193 | ||||
194 | sub add { | |||
195 | my ($self, $type, $args) = @_; | |||
196 | if($self->_check_type($type)) { | |||
197 | my $sub = "add_$type"; | |||
198 | return $self->$sub(%$args); | |||
199 | } else { | |||
200 | carp "Unknown type $type\n"; | |||
201 | } | |||
202 | return; | |||
203 | } | |||
204 | ||||
205 | =head2 Removing Data | |||
206 | ||||
207 | =over 4 | |||
208 | ||||
209 | =item remove() | |||
210 | ||||
211 | $db->remove( I<type>, { I<column values> } ); | |||
212 | ||||
213 | $db->remove( 'scan', { scan => '00123c' } ); | |||
214 | $db->remove( 'frameset', { scan => '00456d', frame => 99 } ); | |||
215 | $db->remove( 'frame', { scan => '00456d', frame => 98, band => 1 } ) | |||
216 | ||||
217 | Valid types are I<frame>, I<frameset>, and I<scan>. | |||
218 | ||||
219 | =back | |||
220 | ||||
221 | =cut | |||
222 | ||||
223 | sub remove { | |||
224 | my ($self, $type, $args) = @_; | |||
225 | if($self->_check_type($type)) { | |||
226 | my $sub = "remove_$type"; | |||
227 | return $self->$sub(%$args); | |||
228 | } else { | |||
229 | carp "Unknown type $type\n"; | |||
230 | } | |||
231 | } | |||
232 | ||||
233 | =head2 Aliases for add() and remove() | |||
234 | ||||
235 | =over 4 | |||
236 | ||||
237 | =item frame() | |||
238 | ||||
239 | $db->frame( I<action>, { I<column values> } ); | |||
240 | ||||
241 | $db->frame( 'add', { scan => '00456d', delivery => '454545', frame => '098', band => 1, | |||
242 | l0_file => 'testframe', scan_end => 0, ra_raw => 15.0, dec_raw => 45.0, | |||
243 | utcs => 1, } ); | |||
244 | $db->frame( 'remove', { frame => '00456d', frame => 98, band => 1 } ); | |||
245 | ||||
246 | Valid actions are I<add> and I<remove>. | |||
247 | ||||
248 | =cut | |||
249 | ||||
250 | sub frame { | |||
251 | my ($self, $action, $args) = @_; | |||
252 | if($self->_check_action($action)) { | |||
253 | my $sub = $action.'_frame'; | |||
254 | return $self->$sub(%$args); | |||
255 | } else { | |||
256 | carp "Unknown action $action"; | |||
257 | } | |||
258 | return; | |||
259 | } | |||
260 | ||||
261 | ||||
262 | =item frameset() | |||
263 | ||||
264 | $db->frameset( I<action>, { I<column values> } ); | |||
265 | ||||
266 | $db->frameset( 'add', { scan => '00456d', frame => 99 } ); | |||
267 | $db->frameset( 'remove', { scan => '00456d', frame => 99 }); | |||
268 | ||||
269 | Valid actions are I<add> and I<remove>. | |||
270 | ||||
271 | =cut | |||
272 | ||||
273 | sub frameset { | |||
274 | my ($self, $action, $args) = @_; | |||
275 | if($self->_check_action($action)) { | |||
276 | my $sub = $action.'_frameset'; | |||
277 | return $self->$sub(%$args); | |||
278 | } else { | |||
279 | carp "Unknown action $action"; | |||
280 | } | |||
281 | return; | |||
282 | } | |||
283 | ||||
284 | =item scan() | |||
285 | ||||
286 | $db->scan( I<action>, { I<column values> } ); | |||
287 | ||||
288 | $db->scan( 'add', { scan => '00123c', delivery => '454545', num_frames => 30 } ); | |||
289 | $db->scan( 'remove', { scan => '00123c' } ); | |||
290 | ||||
291 | Valid actions are I<add> and I<remove>. | |||
292 | ||||
293 | =back | |||
294 | ||||
295 | =cut | |||
296 | ||||
297 | ||||
298 | sub scan { | |||
299 | my ($self, $action, $args) = @_; | |||
300 | if($self->_check_action($action)) { | |||
301 | my $sub = $action.'_scan'; | |||
302 | return $self->$sub(%$args); | |||
303 | } else { | |||
304 | carp "Unknown action $action"; | |||
305 | } | |||
306 | return; | |||
307 | } | |||
308 | ||||
309 | ||||
310 | ######################################################################################## | |||
311 | ######################################################################################## | |||
312 | ||||
313 | # Specific add, remove implementations. | |||
314 | ||||
315 | sub add_frame { | |||
316 | my $self = shift; | |||
317 | my %args = @_; | |||
318 | ||||
319 | my $hptile; | |||
320 | if(defined $args{ra_raw} && defined $args{dec_raw} && ! defined $args{hp_raw}) { | |||
321 | $args{hp_raw} = WISE::CHealPix::ang2pix_ring($self->resultset('Tile')->first->nside, | |||
322 | $args{ra_raw}, | |||
323 | $args{dec_raw} | |||
324 | ); | |||
325 | } | |||
326 | $self->resultset('Frame')->create( { %args } ); | |||
327 | ||||
328 | } | |||
329 | ||||
330 | sub remove_frame { | |||
331 | my $self = shift; | |||
332 | my %args = @_; | |||
333 | my $fr = $self->resultset('Frame')->search( { %args } ); | |||
334 | $fr->delete; | |||
335 | } | |||
336 | ||||
337 | sub add_frameset { | |||
338 | my $self = shift; | |||
339 | my %args = @_; | |||
340 | # this could be more efficient using $schema->popluate('Frame', ...); | |||
341 | # even more so for the whole scan ... | |||
342 | if(defined $args{raw_raw} && defined $args{dec_raw} && ! defined $args{hp_raw}) { | |||
343 | $args{hp_raw} = WISE::CHealPix::ang2pix_ring($self->resultset('Tile')->first->nside, | |||
344 | $args{ra_raw}, | |||
345 | $args{dec_raw} | |||
346 | ); | |||
347 | } | |||
348 | foreach my $band ( qw/1 2 3 4/ ) { | |||
349 | $self->add_frame( %args, band => $band ); | |||
350 | } | |||
351 | } | |||
352 | ||||
353 | sub remove_frameset { | |||
354 | my $self = shift; | |||
355 | my %args = @_; | |||
356 | # don't run a cascaded delete | |||
357 | my $fs = $self->resultset('Frame')->search( {scan => $args{scan}, | |||
358 | frame => $args{frame} } ); | |||
359 | $fs->delete; | |||
360 | } | |||
361 | ||||
362 | sub add_scan { | |||
363 | my $self = shift; | |||
364 | my %args = @_; | |||
365 | my $nframes = $args{num_frames} || 250; | |||
366 | delete $args{num_frames}; | |||
367 | ||||
368 | for my $framenum ( 1 .. $nframes ) { | |||
369 | $args{scan_end} = 1 if($framenum == $nframes); | |||
370 | $self->add_frameset ( %args, frame => $framenum ); | |||
371 | } | |||
372 | ||||
373 | } | |||
374 | ||||
375 | sub remove_scan { | |||
376 | my $self = shift; | |||
377 | my %args = @_; | |||
378 | my $scan = $self->resultset('Frame')->search( { scan => $args{scan} } ); | |||
379 | $scan->delete; | |||
380 | } | |||
381 | ||||
382 | ||||
383 | ######################################################################################## | |||
384 | ######################################################################################## | |||
385 | ||||
386 | =head2 Searching and Updating | |||
387 | ||||
388 | $db->search( { I<column values> } ); | |||
389 | ||||
390 | Most searching functionality is provided by L<DBIx::Class> resultsource objects. It's | |||
391 | worth reading L<DBIx::Class::Manual::Intro> for an introduction to resultsources and | |||
392 | resultsets. Generally speaking, a resultsource is a database table, with a bunch of | |||
393 | added features that you've always wanted, like search. When you search on a resultsource, | |||
394 | you get back a resultset (in scalar context) or a list of row objects. | |||
395 | ||||
396 | A few examples: | |||
397 | ||||
398 | =over 4 | |||
399 | ||||
400 | # This gives you a resultset | |||
401 | my $frameset = $db->search( {scan => '00123c', frame => 13 } ); | |||
402 | ||||
403 | # and this gives you an array of frames | |||
404 | my @frameset = $db->search( {scan => '00123c', frame => 13 } ); | |||
405 | ||||
406 | # If you wanted to update the pipeline status for these frames, you could | |||
407 | foreach my $frame (@frames) { | |||
408 | $frame->update( { pipe_status => $status++ } ); | |||
409 | } | |||
410 | ||||
411 | # but if you wanted to update them to the same status, it is more efficient to | |||
412 | $framset->update( { pipe_status => $stat } ); | |||
413 | ||||
414 | =back | |||
415 | ||||
416 | The resultset has many useful function - see L<DBIx::Class::ResultSet> for | |||
417 | more information. Row functionality is more limited and for the API user it | |||
418 | mainly provides access and updates to individual frames. | |||
419 | ||||
420 | An example of more complicated search: find all the framesets within 1 degree of (15, 45) | |||
421 | taken in the last 4 days that haven't been coadded: | |||
422 | ||||
423 | my (@framesets) = $db->search( { ra => 15, dec => 45, coadd_status => 0, | |||
424 | utcs_start => $start, utcs_span => (4 * 24 * 3600) } ); | |||
425 | ||||
426 | =over | |||
427 | ||||
428 | =item search_utcs() | |||
429 | ||||
430 | $db->search_utcs( { utcs_start => I<begin_time>, utcs_stop => I<end_time>, utcs_span => I<length> } ); | |||
431 | ||||
432 | You may call the time search directly. You must provide enough parameters to fully specify where | |||
433 | and how long in time to search. So it is enough to prove a start or stop time and a span, or a start | |||
434 | and stop, but no span. If start and stop are both ommitted, the stop time is assumed to be | |||
435 | current time. If stop and span are omitted, stop time is assumed to be current time. | |||
436 | ||||
437 | =item search_coord() | |||
438 | ||||
439 | $db->search_coord( { ra => I<ra>, dec => I<dec>, radius => I<radius> } ); | |||
440 | ||||
441 | You may call the coordindate search directly. All units are degrees. The current coordinate search simply reaturns frames | |||
442 | (or a resultset) within I<radius> of I<(ra,dec)>. | |||
443 | ||||
444 | =back | |||
445 | ||||
446 | =cut | |||
447 | ||||
448 | # spent 284ms (1.74+282) within WISE::DB::FrameIndex::search which was called
# once (1.74ms+282ms) at line 677 of /wise/base/deliv/dev/bin/getfix | |||
449 | 12 | 7.6e-5 | 6.3e-6 | my $self = shift; |
450 | my $cond = shift || {}; | |||
451 | my $attr = shift; | |||
452 | ||||
453 | # i have some code below to handle the "special" searches. right now, this means | |||
454 | # utcs time span searches, and ra/dec searches. this code shouldn't be here; i | |||
455 | # think the functionality needs to be pushed into the result source class, but | |||
456 | # am unsure how to implement that. also, the utcs search span can probably be | |||
457 | # done in the usual way, if the API users bother to structure the search args | |||
458 | # correctly. which brings up the larger problem of the search arguments, which do | |||
459 | # not currently match the resultsource search arguments. | |||
460 | ||||
461 | # anyway, this works for non-fancy stuff at the moment. | |||
462 | my ($utcs, $coord); | |||
463 | foreach my $p (qw / ra dec radius/ ) { | |||
464 | 8 | 6.3e-5 | 7.9e-6 | if( grep {/^$p$/ && defined $cond->{$p}} keys %$cond) { |
465 | $coord = 1; last; | |||
466 | } | |||
467 | } | |||
468 | foreach my $p (qw / utcs_start utcs_stop utcs_span / ) { | |||
469 | 18 | 6.2e-5 | 3.4e-6 | if( grep {/^$p$/} keys %$cond) { |
470 | $utcs = 1; last; | |||
471 | } | |||
472 | } | |||
473 | ||||
474 | 3 | 0.00158 | 0.00053 | if( $coord ) { |
475 | my @tiles = $self->_neighbor_hp($cond->{ra}, $cond->{dec}, $cond->{radius}); # spent 277ms making 1 call to WISE::DB::FrameIndex::_neighbor_hp | |||
476 | my @query = _optimize_in_clause('hp_raw',\@tiles); # spent 4.21ms making 1 call to WISE::DB::FrameIndex::_optimize_in_clause | |||
477 | %$cond = (%$cond, @query); | |||
478 | } | |||
479 | if( $utcs ) { | |||
480 | $cond->{utcs} = _utcs_params($cond->{utcs_start}, $cond->{utcs_stop}, $cond->{utcs_span}); | |||
481 | } | |||
482 | ||||
483 | $self->_prune_args( $cond ); # spent 174µs making 1 call to WISE::DB::FrameIndex::_prune_args | |||
484 | ||||
485 | if( wantarray ) { | |||
486 | return $self->resultset('Frame')->search($cond, $attr); | |||
487 | } | |||
488 | my $rs = $self->resultset('Frame')->search($cond, $attr); # spent 450µs making 1 call to DBIx::Class::Schema::resultset
# spent 319µs making 1 call to DBIx::Class::ResultSet::search | |||
489 | #return bless $rs, __PACKAGE__; | |||
490 | return $rs; # !!! Experiment | |||
491 | #return $self->resultset('Frame')->search($cond, $attr); | |||
492 | } | |||
493 | ||||
494 | 3 | 0.00071 | 0.00024 | use vars qw/&find/; # spent 34µs making 1 call to vars::import |
495 | ||||
496 | # find is an alias to search | |||
497 | 1 | 7.0e-6 | 7.0e-6 | *find = \&search; |
498 | ||||
499 | # spent 277ms (4.69+272) within WISE::DB::FrameIndex::_neighbor_hp which was called
# once (4.69ms+272ms) by WISE::DB::FrameIndex::search at line 475 | |||
500 | 12 | 0.00106 | 8.8e-5 | my ($self, $ras, $decs, $radius) = @_; |
501 | $radius = (10/3600) unless defined $radius; | |||
502 | my $nside= $self->resultset('Tile')->first->nside; # spent 26.0ms making 1 call to DBIx::Class::ResultSet::first
# spent 303µs making 1 call to DBIx::Class::Schema::resultset
# spent 41µs making 1 call to Class::Accessor::Grouped::__ANON__[(eval 0)[/wise/base/static/lib/perl5/site_perl/5.10.0/Class/Accessor/Grouped.pm:156]:8] | |||
503 | 1 | 2.2e-5 | 2.2e-5 | my $side = WISE::CHealPix::c2cdist_deg($nside); # spent 26µs making 1 call to WISE::CHealPix::c2cdist_deg |
504 | $radius += $side*sqrt(2)*1.01; # Account for pixel sie and some slop | |||
505 | my @ras = ref($ras) ? @$ras : $ras; | |||
506 | my @decs = ref($decs) ? @$decs : $decs; | |||
507 | my @pix; | |||
508 | my %seen1; | |||
509 | my %seen2; | |||
510 | for my $i (0..$#ras) { | |||
511 | 6 | 0.00363 | 0.00060 | my ($ra,$dec) = ($ras[$i],$decs[$i]); |
512 | next if ! defined $ra || ! defined $dec; | |||
513 | #print "--- $i,$ra,$dec,$radius,$nside\n"; | |||
514 | my $hpix = WISE::CHealPix::ang2pix_ring($nside, $ra, $dec); # spent 40µs making 1 call to WISE::CHealPix::ang2pix_ring | |||
515 | next if $seen1{$hpix}++; | |||
516 | # this can't get you a stripe of constant ra or a strip of constant dec | |||
517 | # and this code doesn't check for those kind of requests | |||
518 | my @new = (grep {! $seen2{$_}++} # spent 246ms making 1 call to WISE::CHealPix::pix_withinr_ring | |||
519 | WISE::CHealPix::pix_withinr_ring($nside, $hpix, $radius)); | |||
520 | push @pix, @new; | |||
521 | #print "--- $hpix => @new\n"; | |||
522 | } | |||
523 | return sort {$a<=>$b} @pix; | |||
524 | } | |||
525 | ||||
526 | sub search_coord { | |||
527 | my $self = shift; | |||
528 | my %args = @_; | |||
529 | my @tiles = $self->_neighbor_hp($args{ra}, $args{dec}, $args{radius}); | |||
530 | if(@tiles) { | |||
531 | $self->_prune_args( \%args ); | |||
532 | my @query = _optimize_in_clause('hp_raw',\@tiles); | |||
533 | %args = (%args, @query); | |||
534 | if( wantarray ) { | |||
535 | return $self->resultset('Frame')->search( {%args}, ); | |||
536 | } | |||
537 | my $rs = $self->resultset('Frame')->search( {%args}, ); | |||
538 | #return bless $rs, __PACKAGE__; | |||
539 | return $rs; | |||
540 | #return $self->resultset('Frame')->search( {%args}, ); | |||
541 | } | |||
542 | return; | |||
543 | } | |||
544 | ||||
545 | sub _utcs_params { | |||
546 | my ($begin, $end, $span) = @_; | |||
547 | if($span && $begin && !$end) { | |||
548 | $end = $begin + $span; | |||
549 | } elsif($span && !$begin && $end) { | |||
550 | $begin = $end - $span; | |||
551 | } elsif($span && !$begin && !$end) { | |||
552 | $end = time(); | |||
553 | $begin = $end - $span; | |||
554 | } | |||
555 | return { '<=' => $end, | |||
556 | '>=' => $begin, }; | |||
557 | } | |||
558 | ||||
559 | # spent 4.21ms within WISE::DB::FrameIndex::_optimize_in_clause which was called
# once (4.21ms+0) by WISE::DB::FrameIndex::search at line 476 | |||
560 | # Look for long sequential runs in the list and pull them out | |||
561 | 11 | 0.00120 | 0.00011 | my $col = shift; |
562 | my $list = shift; | |||
563 | my @list = sort {$a <=> $b} @$list; | |||
564 | my @ranges; # Ranges, queried by 'between' clauses | |||
565 | my @new; # New list of discontinuous segments | |||
566 | my @run; # Runs as they build | |||
567 | for (@list) { | |||
568 | 1991 | 0.00298 | 1.5e-6 | if(@run && $_ == $run[-1]+1) { # Continuous. Build run. |
569 | push @run, $_; | |||
570 | } else { # Discontinuity. End run (if any). | |||
571 | if(@run > 5) { # Long enough | |||
572 | push @ranges,{$col => {-between => [$run[0], $run[-1]]}}; | |||
573 | } elsif(@run) { # Too short | |||
574 | push @new,@run; | |||
575 | } | |||
576 | @run = ($_); | |||
577 | } | |||
578 | } | |||
579 | if(@run > 5) { | |||
580 | push @ranges,{$col => {-between => [$run[0], $run[-1]]}}; | |||
581 | } elsif(@run) { | |||
582 | push @new,@run; | |||
583 | } | |||
584 | ||||
585 | my @query = ((@new ? ($col => {-in => \@new}) : ()), | |||
586 | (@ranges ? (-nest => [-or => \@ranges]) : ())); | |||
587 | ||||
588 | if(@new && @ranges) { | |||
589 | @query = (-or => [@query]); | |||
590 | } | |||
591 | ||||
592 | #use WISE; | |||
593 | #print Dumper \@list,\@query; | |||
594 | ||||
595 | return @query; | |||
596 | } | |||
597 | ||||
598 | sub search_utcs { | |||
599 | my $self = shift; | |||
600 | my %args = @_; | |||
601 | $args{utcs} = _utcs_params($args{utcs_start}, $args{utcs_stop}, $args{utcs_span}); | |||
602 | $self->_prune_args( \%args ); | |||
603 | if( wantarray ) { | |||
604 | return $self->resultset('Frame')->search( {%args} ); | |||
605 | } | |||
606 | my $rs = $self->resultset('Frame')->search( {%args} ); | |||
607 | #return bless $rs, __PACKAGE__; | |||
608 | return $rs; | |||
609 | #return $self->resultset('Frame')->search( { %args } ); | |||
610 | } | |||
611 | ||||
612 | ||||
613 | #=head1 VERSIONING AND SCHEMA DEPLOYMENT | |||
614 | ||||
615 | #=head1 TESTING | |||
616 | ||||
617 | #=head1 DATABASE SIZE | |||
618 | ||||
619 | #=head1 PERFORMANCE AND THROUGHPUT | |||
620 | ||||
621 | #=cut | |||
622 | ||||
623 | 1 | 1.7e-5 | 1.7e-5 | 1; |