Commit 807693280258d2727183031dea30bd3585cf51e2

Authored by knodlseder
1 parent 011098c9

add 'expr' parameter, make time selection optional, allow for automatic use of p…

…ointing as ROI centre
src/ctselect/ctselect.cpp
1 1 /***************************************************************************
2 2 * ctselect - CTA data selection tool *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2011 by Jurgen Knodlseder *
  4 + * copyright (C) 2010-2011 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -21,7 +21,7 @@
21 21 /**
22 22 * @file ctselect.cpp
23 23 * @brief CTA data selection tool implementation
24   - * @author J. Knodlseder
  24 + * @author J. Knoedlseder
25 25 */
26 26  
27 27 /* __ Includes ___________________________________________________________ */
... ... @@ -260,6 +260,9 @@ void ctselect::run(void)
260 260 // Loop over all observation in the container
261 261 for (int i = 0; i < m_obs.size(); ++i) {
262 262  
  263 + // Initialise event filename
  264 + m_infiles.push_back("");
  265 +
263 266 // Get CTA observation
264 267 GCTAObservation* obs = dynamic_cast<GCTAObservation*>(&m_obs[i]);
265 268  
... ... @@ -268,12 +271,17 @@ void ctselect::run(void)
268 271  
269 272 // Write header for observation
270 273 if (logTerse()) {
271   - if (obs->name().length() > 1)
  274 + if (obs->name().length() > 1) {
272 275 log.header3("Observation "+obs->name());
273   - else
  276 + }
  277 + else {
274 278 log.header3("Observation");
  279 + }
275 280 }
276 281  
  282 + // Save event file name (for possible saving)
  283 + m_infiles[i] = obs->eventfile();
  284 +
277 285 // Get temporary file name
278 286 std::string filename = std::tmpnam(NULL);
279 287  
... ... @@ -291,7 +299,7 @@ void ctselect::run(void)
291 299  
292 300 // Remove temporary file
293 301 std::remove(filename.c_str());
294   -
  302 +
295 303 } // endif: had a CTA observation
296 304  
297 305 } // endfor: looped over all observations
... ... @@ -309,9 +317,14 @@ void ctselect::run(void)
309 317  
310 318  
311 319 /***********************************************************************//**
312   - * @brief Save simulated observation
  320 + * @brief Save observation(s) into event file(s)
313 321 *
314   - * This method saves the results.
  322 + * This method saves the observation(s) into event file(s). Each input event
  323 + * file will be saved in a separate output event file. If a single input
  324 + * event file is present, the "outfile" parameter specifies the filename of
  325 + * the output event file. For multiple input event files, "outfile" is used
  326 + * as suffix that is added to the input event file name to create the output
  327 + * filename.
315 328 ***************************************************************************/
316 329 void ctselect::save(void)
317 330 {
... ... @@ -321,7 +334,7 @@ void ctselect::save(void)
321 334 log.header1("Save observations");
322 335 }
323 336  
324   - // Get output filename
  337 + // Get output filename (or prefix for multiple event files)
325 338 m_outfile = (*this)["outfile"].value();
326 339  
327 340 // Loop over all observation in the container
... ... @@ -333,8 +346,34 @@ void ctselect::save(void)
333 346 // Save only if observation is a CTA observation
334 347 if (obs != NULL) {
335 348  
336   - // Save file
337   - obs->save(m_outfile, clobber());
  349 + // Get filename of events file
  350 + std::string eventfile = m_infiles[i];
  351 +
  352 + // Set filename of output events file
  353 + //TODO: we have to strip any path before appending the prefix
  354 + //We may create a special GTools function for this.
  355 + std::string outname = m_outfile;
  356 + if (m_obs.size() > 1) {
  357 + outname += "_" + eventfile;
  358 + //TODO: strip .gz suffix
  359 + }
  360 +
  361 + // Save observation into output events file
  362 + obs->save(outname, clobber());
  363 +
  364 + // Copy over all other extensions that were present in the
  365 + // input event file
  366 + GFits infile(eventfile);
  367 + GFits outfile(outname);
  368 + for (int extno = 1; extno < infile.size(); ++extno) {
  369 + GFitsHDU* hdu = infile.hdu(extno);
  370 + if (hdu->extname() != "EVENTS" && hdu->extname() != "GTI") {
  371 + outfile.append(*hdu);
  372 + }
  373 + }
  374 + infile.close();
  375 + outfile.save(true);
  376 + outfile.close();
338 377  
339 378 } // endif: observation was valid
340 379  
... ... @@ -349,7 +388,7 @@ void ctselect::save(void)
349 388 * @brief Get application parameters
350 389 *
351 390 * Get all task parameters from parameter file or (if required) by querying
352   - * the user.
  391 + * the user. Times are assumed to be in the native CTA MJD format.
353 392 ***************************************************************************/
354 393 void ctselect::get_parameters(void)
355 394 {
... ... @@ -379,6 +418,11 @@ void ctselect::get_parameters(void)
379 418 m_tmax = (*this)["tmax"].real();
380 419 m_emin = (*this)["emin"].real();
381 420 m_emax = (*this)["emax"].real();
  421 + m_expr = (*this)["expr"].string();
  422 +
  423 + // Derive time interval
  424 + m_timemin.time(m_tmin, G_CTA_MJDREF, "days");
  425 + m_timemax.time(m_tmax, G_CTA_MJDREF, "days");
382 426  
383 427 // Return
384 428 return;
... ... @@ -388,46 +432,119 @@ void ctselect::get_parameters(void)
388 432 /***********************************************************************//**
389 433 * @brief Select events
390 434 *
391   - * @param[in] obs CTA observations.
  435 + * @param[in] obs CTA observation.
392 436 * @param[in] filename File name.
393 437 *
394 438 * Select events from a FITS file by making use of the selection possibility
395   - * of the cfitsio library on loading a file.
  439 + * of the cfitsio library on loading a file. A selection string is created
  440 + * from the specified criteria that is appended to the filename so that
  441 + * cfitsio will automatically filter the event data. This selection string
  442 + * is then applied when opening the FITS file. The opened FITS file is then
  443 + * saved into a temporary file which is the loaded into the actual CTA
  444 + * observation, overwriting the old CTA observation. The ROI, GTI and EBounds
  445 + * of the CTA event list are then set accordingly to the specified selection.
  446 + * Finally, the temporary file created during this process is removed.
  447 + *
  448 + * Good Time Intervals of the observation will be limited to the time
  449 + * interval [m_tmin, m_tmax]. If m_tmin=m_tmax=0, no time selection is
  450 + * performed.
396 451 *
397   - * @todo Implement an observation read() method to avoid saving the
398   - * observation to a temporary file.
  452 + * @todo Add an arbitrary selection string.
  453 + * @todo Use INDEF instead of 0.0 for pointing as RA/DEC selection
399 454 ***************************************************************************/
400 455 void ctselect::select_events(GCTAObservation* obs, const std::string& filename)
401 456 {
402 457 // Allocate selection string
403 458 std::string selection;
  459 + char cmin[80];
  460 + char cmax[80];
  461 + char cra[80];
  462 + char cdec[80];
  463 + char crad[80];
  464 +
  465 + // Set requested selections
  466 + bool select_time = (m_tmin != 0.0 || m_tmax != 0.0);
  467 +
  468 + // Set RA/DEC selection
  469 + double ra = m_ra;
  470 + double dec = m_dec;
  471 + if (m_ra == 0.0 && m_dec == 0.0) {
  472 + GTime time;
  473 + const GCTAPointing *pnt = obs->pointing(time);
  474 + ra = pnt->dir().ra_deg();
  475 + dec = pnt->dir().dec_deg();
  476 + }
  477 +
  478 + // Set time selection interval. We make sure here that the time selection
  479 + // interval cannot be wider than the GTIs covering the data. This is done
  480 + // using GGti's reduce() method.
  481 + if (select_time) {
  482 +
  483 + // Reduce GTIs to specified time interval. The complicated cast is
  484 + // necessary here because the gti() method is declared const, so
  485 + // we're not officially allowed to modify the GTIs.
  486 + ((GGti*)(&obs->events()->gti()))->reduce(m_timemin, m_timemax);
  487 +
  488 + } // endif: time selection was required
  489 +
  490 + // Save GTI for later usage
  491 + GGti gti = obs->events()->gti();
404 492  
405 493 // Make time selection
406   - selection = "TIME >= "+str(m_tmin)+" && TIME <= "+str(m_tmax);
407   - if (logTerse())
408   - log << " Time range ................: " << m_tmin << "-" << m_tmax
409   - << std::endl;
410   - if (selection.length() > 0)
411   - selection += " && ";
  494 + if (select_time) {
  495 +
  496 + // Extract effective time interval in native MJD reference
  497 + double tmin = gti.tstart().time();
  498 + double tmax = gti.tstop().time();
  499 +
  500 + // Format time with sufficient accuracy and add to selection string
  501 + sprintf(cmin, "%.8f", tmin);
  502 + sprintf(cmax, "%.8f", tmax);
  503 + selection = "TIME >= "+std::string(cmin)+" && TIME <= "+std::string(cmax);
  504 + if (logTerse()) {
  505 + log << " Time range ................: " << tmin << "-" << tmax
  506 + << std::endl;
  507 + }
  508 + if (selection.length() > 0) {
  509 + selection += " && ";
  510 + }
  511 + }
412 512  
413 513 // Make energy selection
414   - selection += "ENERGY >= "+str(m_emin)+" && ENERGY <= "+str(m_emax);
415   - if (logTerse())
  514 + sprintf(cmin, "%.8f", m_emin);
  515 + sprintf(cmax, "%.8f", m_emax);
  516 + selection += "ENERGY >= "+std::string(cmin)+" && ENERGY <= "+std::string(cmax);
  517 + if (logTerse()) {
416 518 log << " Energy range ..............: " << m_emin << "-" << m_emax
417 519 << " TeV" << std::endl;
418   - if (selection.length() > 0)
  520 + }
  521 + if (selection.length() > 0) {
419 522 selection += " && ";
  523 + }
420 524  
421 525 // Make ROI selection
422   - selection += "ANGSEP("+str(m_ra)+","+str(m_dec)+",RA,DEC) <= "+str(m_rad);
  526 + sprintf(cra, "%.6f", ra);
  527 + sprintf(cdec, "%.6f", dec);
  528 + sprintf(crad, "%.6f", m_rad);
  529 + selection += "ANGSEP("+std::string(cra)+"," +
  530 + std::string(cdec)+",RA,DEC) <= " +
  531 + std::string(crad);
423 532 if (logTerse()) {
424   - log << " Acceptance cone centre ....: RA=" << m_ra << ", DEC=" << m_dec
  533 + log << " Acceptance cone centre ....: RA=" << ra << ", DEC=" << dec
425 534 << " deg" << std::endl;
426 535 log << " Acceptance cone radius ....: " << m_rad << " deg" << std::endl;
427 536 }
428 537 if (logTerse())
429 538 log << " cfitsio selection .........: " << selection << std::endl;
430 539  
  540 + // Add additional expression
  541 + if (strip_whitespace(m_expr).length() > 0) {
  542 + if (selection.length() > 0) {
  543 + selection += " && ";
  544 + }
  545 + selection += "("+strip_whitespace(m_expr)+")";
  546 + }
  547 +
431 548 // Build input filename including selection expression
432 549 std::string expression = filename;
433 550 if (selection.length() > 0)
... ... @@ -460,18 +577,12 @@ void ctselect::select_events(GCTAObservation* obs, const std::string&amp; filename)
460 577 // Set ROI
461 578 GCTARoi roi;
462 579 GCTAInstDir instdir;
463   - instdir.radec_deg(m_ra, m_dec);
  580 + instdir.radec_deg(ra, dec);
464 581 roi.centre(instdir);
465 582 roi.radius(m_rad);
466 583 list->roi(roi);
467 584  
468 585 // Set GTI
469   - GGti gti;
470   - GTime tstart;
471   - GTime tstop;
472   - tstart.met(m_tmin);
473   - tstop.met(m_tmax);
474   - gti.append(tstart, tstop);
475 586 list->gti(gti);
476 587  
477 588 // Set energy boundaries
... ... @@ -506,6 +617,9 @@ void ctselect::init_members(void)
506 617 m_infile.clear();
507 618 m_outfile.clear();
508 619 m_obs.clear();
  620 + m_infiles.clear();
  621 + m_timemin.clear();
  622 + m_timemax.clear();
509 623 m_ra = 0.0;
510 624 m_dec = 0.0;
511 625 m_rad = 0.0;
... ... @@ -533,6 +647,9 @@ void ctselect::copy_members(const ctselect&amp; app)
533 647 m_infile = app.m_infile;
534 648 m_outfile = app.m_outfile;
535 649 m_obs = app.m_obs;
  650 + m_infiles = app.m_infiles;
  651 + m_timemin = app.m_timemin;
  652 + m_timemax = app.m_timemax;
536 653 m_ra = app.m_ra;
537 654 m_dec = app.m_dec;
538 655 m_rad = app.m_rad;
... ...
src/ctselect/ctselect.hpp
1 1 /***************************************************************************
2 2 * ctselect - CTA data selection tool *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2011 by Jurgen Knodlseder *
  4 + * copyright (C) 2010-2011 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -21,19 +21,21 @@
21 21 /**
22 22 * @file ctselect.hpp
23 23 * @brief CTA data selection tool definition
24   - * @author J. Knodlseder
  24 + * @author J. Knoedlseder
25 25 */
26 26  
27 27 #ifndef CTSELECT_HPP
28 28 #define CTSELECT_HPP
29 29  
30 30 /* __ Includes ___________________________________________________________ */
  31 +#include <vector>
  32 +#include <string>
31 33 #include "GammaLib.hpp"
32 34 #include "GCTALib.hpp"
33 35  
34 36 /* __Definitions _________________________________________________________ */
35 37 #define CTSELECT_NAME "ctselect"
36   -#define CTSELECT_VERSION "00-02-03"
  38 +#define CTSELECT_VERSION "00-03-00"
37 39  
38 40  
39 41 /***********************************************************************//**
... ... @@ -70,18 +72,22 @@ protected:
70 72 std::string check_infile(const std::string& filename) const;
71 73  
72 74 // User parameters
73   - std::string m_infile; //!< Input event list
74   - std::string m_outfile; //!< Output event list
75   - double m_ra; //!< RA of ROI centre
76   - double m_dec; //!< DEC of ROI centre
77   - double m_rad; //!< ROI radius
78   - double m_tmin; //!< Start time
79   - double m_tmax; //!< Stop time
80   - double m_emin; //!< Lower energy
81   - double m_emax; //!< Upper energy
  75 + std::string m_infile; //!< Input event list
  76 + std::string m_outfile; //!< Output event list
  77 + double m_ra; //!< RA of ROI centre
  78 + double m_dec; //!< DEC of ROI centre
  79 + double m_rad; //!< ROI radius
  80 + double m_tmin; //!< Start time
  81 + double m_tmax; //!< Stop time
  82 + double m_emin; //!< Lower energy
  83 + double m_emax; //!< Upper energy
  84 + std::string m_expr; //!< Selection expression
82 85  
83 86 // Protected members
84   - GObservations m_obs; //!< Observations container
  87 + GObservations m_obs; //!< Observations container
  88 + std::vector<std::string> m_infiles; //!< Input event filenames
  89 + GTime m_timemin; //!< Earliest time
  90 + GTime m_timemax; //!< Latest time
85 91 };
86 92  
87 93 #endif /* CTSELECT_HPP */
... ...