GammaLib 2.0.0
Loading...
Searching...
No Matches
GCOMSelection.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GCOMSelection.cpp - COMPTEL selection set class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2017-2022 by Juergen Knoedlseder *
5 * ----------------------------------------------------------------------- *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19 * *
20 ***************************************************************************/
21/**
22 * @file GCOMSelection.cpp
23 * @brief COMPTEL selection set class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include "GFitsHDU.hpp"
32#include "GCOMTools.hpp"
33#include "GCOMSupport.hpp"
34#include "GCOMStatus.hpp"
35#include "GCOMSelection.hpp"
36#include "GCOMEventAtom.hpp"
37
38/* __ Method name definitions ____________________________________________ */
39#define G_FPMTFLAG "GCOMSelection::fpmtflag(int&)"
40#define G_USE_D1_GET "GCOMSelection::use_d1(int&)"
41#define G_USE_D1_SET "GCOMSelection::use_d1(int&, bool&)"
42#define G_USE_D2_GET "GCOMSelection::use_d2(int&)"
43#define G_USE_D2_SET "GCOMSelection::use_d2(int&, bool&)"
44
45/* __ Macros _____________________________________________________________ */
46
47/* __ Coding definitions _________________________________________________ */
48
49/* __ Debug definitions __________________________________________________ */
50
51
52
53/*==========================================================================
54 = =
55 = Constructors/destructors =
56 = =
57 ==========================================================================*/
58
59/***********************************************************************//**
60 * @brief Void constructor
61 ***************************************************************************/
63{
64 // Initialise class members
66
67 // Return
68 return;
69}
70
71
72/***********************************************************************//**
73 * @brief Copy constructor
74 *
75 * @param[in] select COMPTEL selection set.
76 ***************************************************************************/
78{
79 // Initialise class members
81
82 // Copy members
83 copy_members(select);
84
85 // Return
86 return;
87}
88
89
90/***********************************************************************//**
91 * @brief Destructor
92 ***************************************************************************/
94{
95 // Free members
97
98 // Return
99 return;
100}
101
102
103/*==========================================================================
104 = =
105 = Operators =
106 = =
107 ==========================================================================*/
108
109/***********************************************************************//**
110 * @brief Assignment operator
111 *
112 * @param[in] select COMPTEL selection set.
113 * @return COMPTEL selection set.
114 ***************************************************************************/
116{
117 // Execute only if object is not identical
118 if (this != &select) {
119
120 // Free members
121 free_members();
122
123 // Initialise private members
124 init_members();
125
126 // Copy members
127 copy_members(select);
128
129 } // endif: object was not identical
130
131 // Return this object
132 return *this;
133}
134
135
136/*==========================================================================
137 = =
138 = Public methods =
139 = =
140 ==========================================================================*/
141
142/***********************************************************************//**
143 * @brief Clear COMPTEL selection set
144 ***************************************************************************/
146{
147 // Free members
148 free_members();
149
150 // Initialise private members
151 init_members();
152
153 // Return
154 return;
155}
156
157
158/***********************************************************************//**
159 * @brief Clone COMPTEL selection set
160 *
161 * @return Pointer to deep copy of COMPTEL selection set.
162 ***************************************************************************/
164{
165 return new GCOMSelection(*this);
166}
167
168
169/***********************************************************************//**
170 * @brief Initialise selection statistics
171 ***************************************************************************/
173{
174 // Initialise statistics members
178 m_num_e1_min = 0;
179 m_num_e1_max = 0;
180 m_num_e2_min = 0;
181 m_num_e2_max = 0;
182 m_num_tof_min = 0;
183 m_num_tof_max = 0;
184 m_num_psd_min = 0;
185 m_num_psd_max = 0;
194 m_num_fpmt = 0;
195 for (int i = 0; i < 7; ++i) {
196 m_num_d1[i] = 0;
197 }
198 for (int i = 0; i < 14; ++i) {
199 m_num_d2[i] = 0;
200 }
201
202 // Return
203 return;
204}
205
206
207/***********************************************************************//**
208 * @brief Check if event should be used
209 *
210 * @param[in] event Event.
211 * @return True if event should be used, false otherwise.
212 *
213 * Checks if an event should be used for DRE binning.
214 ***************************************************************************/
216{
217 // Initialise D1 & D2 module status
218 static const GCOMStatus status;
219
220 // Initialise usage flag
221 bool use = true;
222
223 // Increment number of checked events
225
226 // Check for bad minitelescopes
227 if (event.modcom() < 1 || event.modcom() > 98) {
229 use = false;
230 }
231
232 // Check whether the event has a scatter angle determined. This is
233 // signaled by a scatter angle -10e20 in radians.
234 else if (event.theta() < -1.0e3) {
236 use = false;
237 }
238
239 // Apply event selection
240 else if (event.e1() < m_e1_min) {
241 m_num_e1_min++;
242 use = false;
243 }
244 else if (event.e1() > m_e1_max) {
245 m_num_e1_max++;
246 use = false;
247 }
248 else if (event.e2() < m_e2_min) {
249 m_num_e2_min++;
250 use = false;
251 }
252 else if (event.e2() > m_e2_max) {
253 m_num_e2_max++;
254 use = false;
255 }
256 else if (event.tof() < m_tof_min) {
258 use = false;
259 }
260 else if (event.tof() > m_tof_max) {
262 use = false;
263 }
264 else if (event.psd() < m_psd_min) {
266 use = false;
267 }
268 else if (event.psd() > m_psd_max) {
270 use = false;
271 }
272 else if (event.reflag() < m_reflag_min) {
274 use = false;
275 }
276 else if (event.reflag() > m_reflag_max) {
278 use = false;
279 }
280 else if (event.veto() < m_vetoflag_min) {
282 use = false;
283 }
284 else if (event.veto() > m_vetoflag_max) {
286 use = false;
287 }
288
289 // If event should be used then handle now the module status and
290 // decide whether it should be rejected
291 if (use) {
292
293 // Extract module IDs from MODCOM
294 int id2 = (event.modcom()-1)/7 + 1; // [1-14]
295 int id1 = event.modcom() - (id2-1) * 7; // [1-7]
296
297 // Get event TJD
298 int tjd = gammalib::com_tjd(event.time());
299
300 // Set D1 and D2 status
301 int d1status = status.d1status(tjd, id1);
302 int d2status = status.d2status(tjd, id2);
303
304 // Exclude event if the coresponding modules should not be used
305 if (!m_use_d1[id1-1]) {
307 use = false;
308 }
309 else if (!m_use_d2[id2-1]) {
311 use = false;
312 }
313
314 // Exclude event if the corresponding modules are signalled
315 // as off
316 else if (d1status != 1) {
318 use = false;
319 }
320 else if (d2status < 1) {
322 use = false;
323 }
324
325 // Handle D2 modules with failed PMTs based on value of
326 // failure flag
327 else if (d2status > 1) {
328
329 // If failure flag = 0 then reject event and signal that the
330 // module was off
331 if (m_fpmtflag == 0) {
333 use = false;
334 }
335
336 // ... otherwise if failure flag = 2 and the module has a
337 // valid exclusion circle then reject event if it is
338 // within the exclusion circle; if the module has no
339 // exclusion region then reject the entire module and
340 // signal that it was off.
341 else if (m_fpmtflag == 2) {
342 double r = gammalib::com_exd2r(id2);
343 if (r >= 0.1) {
344 double dx = gammalib::com_exd2x(id2) - 0.1 * event.x_d2();
345 double dy = gammalib::com_exd2y(id2) - 0.1 * event.y_d2();
346 double dsq = dx*dx + dy*dy;
347 double rsq = r*r;
348 if (dsq <= rsq) {
349 m_num_fpmt++;
350 use = false;
351 }
352 }
353 else {
355 use = false;
356 }
357 }
358
359 } // endif: handled D2 modules with failed PMTs
360
361 } // endif: handled module status
362
363 // Update acceptance and rejection statistics
364 if (use) {
365
366 // Extract module IDs from MODCOM
367 int id2 = (event.modcom()-1)/7 + 1; // [1-14]
368 int id1 = event.modcom() - (id2-1) * 7; // [1-7]
369
370 // Update statistics
372 m_num_d1[id1-1]++;
373 m_num_d2[id2-1]++;
374
375 }
376 else {
378 }
379
380 // Return usage flag
381 return use;
382}
383
384
385/***********************************************************************//**
386 * @brief Set failed PMT flag for D2 modules
387 *
388 * @param[in] fpmtflag Failed PMT flag for D2 modules.
389 *
390 * Set the failed PMT flag for D2 modules. The following values can be
391 * set:
392 * - 0: excluded D2 modules with failed PMTs
393 * - 1: include D2 modules with failed PMTs
394 * - 2: include D2 modules with failed PMTs by excluding zone around failed
395 * PMTs
396 ***************************************************************************/
397void GCOMSelection::fpmtflag(const int& fpmtflag)
398{
399 // Check validify of values
401 std::string msg = "Invalid value "+gammalib::str(fpmtflag)+
402 " specified for failed PMT flag for D2 modules. "
403 "Please specify 0, 1 or 2.";
405 }
406
407 // Set flag
409
410 // Return
411 return;
412}
413
414
415/***********************************************************************//**
416 * @brief Return D1 module usage flag
417 *
418 * @param[in] id1 D1 module identifier [0,...,6].
419 * @return True if D1 module @p id1 should be used.
420 ***************************************************************************/
421const bool& GCOMSelection::use_d1(const int& id1) const
422{
423 // Check module validity range
424 if (id1 < 0 || id1 > 6) {
425 std::string msg = "Invalid D1 module identifier "+gammalib::str(id1)+
426 " specified. The D1 module identifier needs to be "
427 "comprised within 0 and 6.";
429 }
430
431 // Return usage flag
432 return (m_use_d1[id1]);
433}
434
435
436/***********************************************************************//**
437 * @brief Set D1 module usage flag
438 *
439 * @param[in] id1 D1 module identifier [0,...,6].
440 * @param[in] use D1 module usage.
441 ***************************************************************************/
442void GCOMSelection::use_d1(const int& id1, const bool& use)
443{
444 // Check module validity range
445 if (id1 < 0 || id1 > 6) {
446 std::string msg = "Invalid D1 module identifier "+gammalib::str(id1)+
447 " specified. The D1 module identifier needs to be "
448 "comprised within 0 and 6.";
450 }
451
452 // Set usage flag
453 m_use_d1[id1] = use;
454
455 // Return
456 return;
457}
458
459
460/***********************************************************************//**
461 * @brief Return D2 module usage flag
462 *
463 * @param[in] id2 D2 module identifier [0,...,13].
464 * @return True if D2 module @p id2 should be used.
465 ***************************************************************************/
466const bool& GCOMSelection::use_d2(const int& id2) const
467{
468 // Check module validity range
469 if (id2 < 0 || id2 > 13) {
470 std::string msg = "Invalid D2 module identifier "+gammalib::str(id2)+
471 " specified. The D2 module identifier needs to be "
472 "comprised within 0 and 13.";
474 }
475
476 // Return usage flag
477 return (m_use_d2[id2]);
478}
479
480
481/***********************************************************************//**
482 * @brief Set D2 module usage flag
483 *
484 * @param[in] id2 D2 module identifier [0,...,13].
485 * @param[in] use D2 module usage.
486 ***************************************************************************/
487void GCOMSelection::use_d2(const int& id2, const bool& use)
488{
489 // Check module validity range
490 if (id2 < 0 || id2 > 13) {
491 std::string msg = "Invalid D2 module identifier "+gammalib::str(id2)+
492 " specified. The D2 module identifier needs to be "
493 "comprised within 0 and 13.";
495 }
496
497 // Set usage flag
498 m_use_d2[id2] = use;
499
500 // Return
501 return;
502}
503
504
505/***********************************************************************//**
506 * @brief Read selection set from FITS HDU keywords
507 *
508 * @param[in] hdu FITS HDU.
509 ***************************************************************************/
511{
512 // Read D1 energy selection
513 if (hdu.has_card("D1EMIN") && hdu.has_card("D1EMAX")) {
514 m_e1_min = hdu.real("D1EMIN");
515 m_e1_max = hdu.real("D1EMAX");
516 }
517
518 // Read D2 energy selection
519 if (hdu.has_card("D2EMIN") && hdu.has_card("D2EMAX")) {
520 m_e2_min = hdu.real("D2EMIN");
521 m_e2_max = hdu.real("D2EMAX");
522 }
523
524 // Read ToF selection
525 if (hdu.has_card("TOFMIN") && hdu.has_card("TOFMAX")) {
526 m_tof_min = hdu.integer("TOFMIN");
527 m_tof_max = hdu.integer("TOFMAX");
528 }
529
530 // Read PSD selection
531 if (hdu.has_card("PSDMIN") && hdu.has_card("PSDMAX")) {
532 m_psd_min = hdu.integer("PSDMIN");
533 m_psd_max = hdu.integer("PSDMAX");
534 }
535
536 // Read rejection flag selection
537 if (hdu.has_card("RFLMIN") && hdu.has_card("RFLMAX")) {
538 m_reflag_min = hdu.integer("RFLMIN");
539 m_reflag_max = hdu.integer("RFLMAX");
540 }
541
542 // Read veto flag selection
543 if (hdu.has_card("VFLMIN") && hdu.has_card("VFLMAX")) {
544 m_vetoflag_min = hdu.integer("VFLMIN");
545 m_vetoflag_max = hdu.integer("VFLMAX");
546 }
547
548 // Read D2 PMT failure handling flag
549 if (hdu.has_card("D2FPMT")) {
550 m_fpmtflag = hdu.integer("D2FPMT");
551 }
552
553 // Read D1 module usage flag
554 if (hdu.has_card("D1USE")) {
555 std::string use = gammalib::strip_whitespace(hdu.string("D1USE"));
556 if (use.length() == 7) {
557 for (int i = 0; i < 7; ++i) {
558 m_use_d1[i] = (use[i] == '1');
559 }
560 }
561 }
562
563 // Read D2 module usage flag
564 if (hdu.has_card("D2USE")) {
565 std::string use = gammalib::strip_whitespace(hdu.string("D2USE"));
566 if (use.length() == 14) {
567 for (int i = 0; i < 14; ++i) {
568 m_use_d2[i] = (use[i] == '1');
569 }
570 }
571 }
572
573 // Read selection statistics
574 if (hdu.has_card("NEVCHK")) {
575 m_num_events_checked = hdu.integer("NEVCHK");
576 }
577 if (hdu.has_card("NEVUSE")) {
578 m_num_events_used = hdu.integer("NEVUSE");
579 }
580 if (hdu.has_card("NEVREJ")) {
581 m_num_events_rejected = hdu.integer("NEVREJ");
582 }
583 if (hdu.has_card("ND1ELO") && hdu.has_card("ND1EHI")) {
584 m_num_e1_min = hdu.integer("ND1ELO");
585 m_num_e1_max = hdu.integer("ND1EHI");
586 }
587 if (hdu.has_card("ND2ELO") && hdu.has_card("ND2EHI")) {
588 m_num_e2_min = hdu.integer("ND2ELO");
589 m_num_e2_max = hdu.integer("ND2EHI");
590 }
591 if (hdu.has_card("NTOFLO") && hdu.has_card("NTOFHI")) {
592 m_num_tof_min = hdu.integer("NTOFLO");
593 m_num_tof_max = hdu.integer("NTOFHI");
594 }
595 if (hdu.has_card("NPSDLO") && hdu.has_card("NPSDHI")) {
596 m_num_psd_min = hdu.integer("NPSDLO");
597 m_num_psd_max = hdu.integer("NPSDHI");
598 }
599 if (hdu.has_card("NRFLLO") && hdu.has_card("NRFLHI")) {
600 m_num_reflag_min = hdu.integer("NRFLLO");
601 m_num_reflag_max = hdu.integer("NRFLHI");
602 }
603 if (hdu.has_card("NVFLLO") && hdu.has_card("NVFLHI")) {
604 m_num_vetoflag_min = hdu.integer("NVFLLO");
605 m_num_vetoflag_max = hdu.integer("NVFLHI");
606 }
607 if (hdu.has_card("NNOSCT")) {
608 m_num_no_scatter = hdu.integer("NNOSCT");
609 }
610 for (int i = 0; i < 7; ++i) {
611 std::string key = "ND1-"+gammalib::str(i+1,"%2.2d");
612 if (hdu.has_card(key)) {
613 m_num_d1[i] = hdu.integer(key);
614 }
615 }
616 for (int i = 0; i < 14; ++i) {
617 std::string key = "ND2-"+gammalib::str(i+1,"%2.2d");
618 if (hdu.has_card(key)) {
619 m_num_d2[i] = hdu.integer(key);
620 }
621 }
622 if (hdu.has_card("ND1OFF")) {
623 m_num_d1module_off = hdu.integer("ND1OFF");
624 }
625 if (hdu.has_card("ND2OFF")) {
626 m_num_d2module_off = hdu.integer("ND2OFF");
627 }
628 if (hdu.has_card("ND2FPM")) {
629 m_num_fpmt = hdu.integer("ND2FPM");
630 }
631
632 // Return
633 return;
634}
635
636
637/***********************************************************************//**
638 * @brief Write selection set keywords into FITS HDU
639 *
640 * @param[in] hdu FITS HDU.
641 ***************************************************************************/
643{
644 // Write D1 energy selection
645 hdu.card("D1EMIN", m_e1_min, "[MeV] Minimum D1 energy deposit");
646 hdu.card("D1EMAX", m_e1_max, "[MeV] Maximum D1 energy deposit");
647
648 // Write D2 energy selection
649 hdu.card("D2EMIN", m_e2_min, "[MeV] Minimum D2 energy deposit");
650 hdu.card("D2EMAX", m_e2_max, "[MeV] Maximum D2 energy deposit");
651
652 // Write ToF selection
653 hdu.card("TOFMIN", m_tof_min, "ToF selection minimum");
654 hdu.card("TOFMAX", m_tof_max, "ToF selection maximum");
655
656 // Write PSD selection
657 hdu.card("PSDMIN", m_psd_min, "PSD selection minimum");
658 hdu.card("PSDMAX", m_psd_max, "PSD selection maximum");
659
660 // Write rejection flag selection
661 hdu.card("RFLMIN", m_reflag_min, "Rejection flag minimum");
662 hdu.card("RFLMAX", m_reflag_max, "Rejection flag maximum");
663
664 // Write veto flag selection
665 hdu.card("VFLMIN", m_vetoflag_min, "Veto flag minimum");
666 hdu.card("VFLMAX", m_vetoflag_max, "Veto flag maximum");
667
668 // Write D2 PMT failure handling flag
669 hdu.card("D2FPMT", m_fpmtflag, "D2 PMT failure handling");
670
671 // Write D1 module usage
672 std::string d1use = "0000000";
673 for (int i = 0; i < 7; ++i) {
674 if (m_use_d1[i]) {
675 d1use[i] = '1';
676 }
677 }
678 hdu.card("D1USE", d1use, "D1 module usage");
679
680 // Write D2 module usage
681 std::string d2use = "00000000000000";
682 for (int i = 0; i < 14; ++i) {
683 if (m_use_d2[i]) {
684 d2use[i] = '1';
685 }
686 }
687 hdu.card("D2USE", d2use, "D2 module usage");
688
689 // Write selection statistics
690 hdu.card("NEVCHK", m_num_events_checked, "Number of checked events");
691 hdu.card("NEVUSE", m_num_events_used, "Number of used events");
692 hdu.card("NEVREJ", m_num_events_rejected, "Number of rejected events");
693 hdu.card("ND1ELO", m_num_e1_min, "Number of events < D1EMIN");
694 hdu.card("ND1EHI", m_num_e1_max, "Number of events > D1EMAX");
695 hdu.card("ND2ELO", m_num_e2_min, "Number of events < D2EMIN");
696 hdu.card("ND2EHI", m_num_e2_max, "Number of events > D2EMAX");
697 hdu.card("NTOFLO", m_num_tof_min, "Number of events < TOFMIN");
698 hdu.card("NTOFHI", m_num_tof_max, "Number of events > TOFMIN");
699 hdu.card("NPSDLO", m_num_psd_min, "Number of events < PSDMIN");
700 hdu.card("NPSDHI", m_num_psd_max, "Number of events > PSDMAX");
701 hdu.card("NRFLLO", m_num_reflag_min, "Number of events < RFLMIN");
702 hdu.card("NRFLHI", m_num_reflag_max, "Number of events > RFLMAX");
703 hdu.card("NVFLLO", m_num_vetoflag_min, "Number of events < VFLMIN");
704 hdu.card("NVFLHI", m_num_vetoflag_max, "Number of events > VFLMAX");
705 hdu.card("NNOSCT", m_num_no_scatter, "Number of events w/o scatter angle");
706 hdu.card("NINVMT", m_num_invalid_modcom, "Number of events with invalid minitelescope");
707 for (int i = 0; i < 7; ++i) {
708 std::string key = "ND1-"+gammalib::str(i+1,"%2.2d");
709 std::string com = "Number of events in D1 module "+gammalib::str(i+1);
710 hdu.card(key, m_num_d1[i], com);
711 }
712 for (int i = 0; i < 14; ++i) {
713 std::string key = "ND2-"+gammalib::str(i+1,"%2.2d");
714 std::string com = "Number of events in D2 module "+gammalib::str(i+1);
715 hdu.card(key, m_num_d2[i], com);
716 }
717 hdu.card("ND1OFF", m_num_d1module_off, "Number of events with D1 module off");
718 hdu.card("ND2OFF", m_num_d2module_off, "Number of events with D2 module off");
719 hdu.card("ND2FPM", m_num_fpmt, "Number of events excluded due to failed PMTs");
720
721 // Return
722 return;
723}
724
725
726/***********************************************************************//**
727 * @brief Set orbital period
728 *
729 * @param[in] period Orbital period (days).
730 * @param[in] time Time of phase zero.
731 *
732 * Set the orbital phase for orbital phase selection.
733 ***************************************************************************/
734void GCOMSelection::orbital_period(const double& period, const GTime& time)
735{
736 // Clear temporal phase curve
738
739 // Get frequency of orbit in units of Hz
740 double f0 = 1.0 / (period * gammalib::sec_in_day);
741
742 // Set phase curve elements
743 m_orbital_phase_curve.mjd(time); // Reference time
744 m_orbital_phase_curve.phase(0.0); // Phase at reference time
745 m_orbital_phase_curve.f0(f0); // Frequency at reference time
746 m_orbital_phase_curve.f1(0.0); // No frequency derivative
747 m_orbital_phase_curve.f2(0.0); // No 2nd frequency derivative
748
749 // Return
750 return;
751}
752
753
754/***********************************************************************//**
755 * @brief Print COMPTEL selection set
756 *
757 * @param[in] chatter Chattiness.
758 * @return String containing COMPTEL selection set information.
759 ***************************************************************************/
760std::string GCOMSelection::print(const GChatter& chatter) const
761{
762 // Initialise result string
763 std::string result;
764
765 // Continue only if chatter is not silent
766 if (chatter != SILENT) {
767
768 // Append header
769 result.append("=== GCOMSelection ===");
770
771 // Append number of checked events
772 result.append("\n"+gammalib::parformat("Checked events"));
773 result.append(gammalib::str(m_num_events_checked));
774 result.append("\n"+gammalib::parformat("Accepted events"));
775 result.append(gammalib::str(m_num_events_used));
776 result.append("\n"+gammalib::parformat("Rejected events"));
777 result.append(gammalib::str(m_num_events_rejected));
778
779 // Append E1 selection statistics
780 result.append("\n"+gammalib::parformat("E1 selection"));
781 result.append(gammalib::str(m_num_e1_min)+" < [");
782 result.append(gammalib::str(m_e1_min)+" - ");
783 result.append(gammalib::str(m_e1_max)+" MeV] < ");
784 result.append(gammalib::str(m_num_e1_max));
785
786 // Append E2 selection statistics
787 result.append("\n"+gammalib::parformat("E2 selection"));
788 result.append(gammalib::str(m_num_e2_min)+" < [");
789 result.append(gammalib::str(m_e2_min)+" - ");
790 result.append(gammalib::str(m_e2_max)+" MeV] < ");
791 result.append(gammalib::str(m_num_e2_max));
792
793 // Append TOF selection statistics
794 result.append("\n"+gammalib::parformat("TOF selection"));
795 result.append(gammalib::str(m_num_tof_min)+" < [");
796 result.append(gammalib::str(m_tof_min)+" - ");
797 result.append(gammalib::str(m_tof_max)+"] < ");
798 result.append(gammalib::str(m_num_tof_max));
799
800 // Append PSD selection statistics
801 result.append("\n"+gammalib::parformat("PSD selection"));
802 result.append(gammalib::str(m_num_psd_min)+" < [");
803 result.append(gammalib::str(m_psd_min)+" - ");
804 result.append(gammalib::str(m_psd_max)+"] < ");
805 result.append(gammalib::str(m_num_psd_max));
806
807 // Append rejection flag selection statistics
808 result.append("\n"+gammalib::parformat("Rejection flag selection"));
809 result.append(gammalib::str(m_num_reflag_min)+" < [");
810 result.append(gammalib::str(m_reflag_min)+" - ");
811 result.append(gammalib::str(m_reflag_max)+"] < ");
812 result.append(gammalib::str(m_num_reflag_max));
813
814 // Append veto flag selection statistics
815 result.append("\n"+gammalib::parformat("Veto flag selection"));
816 result.append(gammalib::str(m_num_vetoflag_min)+" < [");
817 result.append(gammalib::str(m_vetoflag_min)+" - ");
818 result.append(gammalib::str(m_vetoflag_max)+"] < ");
819 result.append(gammalib::str(m_num_vetoflag_max));
820
821 // Append D1 module usage
822 for (int i = 0; i < 7; ++i) {
823 result.append("\n"+gammalib::parformat("D1 module "+gammalib::str(i+1)));
824 result.append(gammalib::str(m_num_d1[i]));
825 if (m_use_d1[i]) {
826 result.append(" [use]");
827 }
828 else {
829 result.append(" [don't use]");
830 }
831 }
832
833 // Append D2 module usage
834 for (int i = 0; i < 14; ++i) {
835 result.append("\n"+gammalib::parformat("D2 module "+gammalib::str(i+1)));
836 result.append(gammalib::str(m_num_d2[i]));
837 if (m_use_d2[i]) {
838 result.append(" [use]");
839 }
840 else {
841 result.append(" [don't use]");
842 }
843 }
844
845 // Append D1 module off
846 result.append("\n"+gammalib::parformat("D1 modules off"));
847 result.append(gammalib::str(m_num_d1module_off));
848
849 // Append D2 module off
850 result.append("\n"+gammalib::parformat("D2 modules off"));
851 result.append(gammalib::str(m_num_d2module_off));
852
853 // Append D2 PMT failure handling statistics
854 result.append("\n"+gammalib::parformat("D2 PMT failure"));
855 result.append(gammalib::str(m_num_fpmt)+" [");
856 result.append(gammalib::str(m_fpmtflag)+"]");
857
858 // Append other statistics
859 result.append("\n"+gammalib::parformat("No scatter angle"));
860 result.append(gammalib::str(m_num_no_scatter));
861 result.append("\n"+gammalib::parformat("Invalid minitelescope"));
862 result.append(gammalib::str(m_num_invalid_modcom));
863
864 // Append orbital phase selection if it exists
865 if (!m_orbital_phases.is_empty()) {
866 result.append("\n"+m_orbital_phases.print());
867 result.append("\n"+m_orbital_phase_curve.print());
868 }
869
870 // Append pulsar if it exists
871 if (!m_pulsar.is_empty()) {
872 result.append("\n"+m_pulsar.print());
873 }
874
875 // Append pulsar phase selection if it exists
876 if (!m_pulsar_phases.is_empty()) {
877 result.append("\n"+m_pulsar_phases.print());
878 }
879
880 } // endif: chatter was not silent
881
882 // Return result
883 return result;
884}
885
886
887/*==========================================================================
888 = =
889 = Private methods =
890 = =
891 ==========================================================================*/
892
893/***********************************************************************//**
894 * @brief Initialise class members
895 ***************************************************************************/
897{
898 // Initialise members
899 m_e1_min = 0.070; //!< Minimum D1 energy deposit (MeV)
900 m_e1_max = 20.0; //!< Maximum D1 energy deposit (MeV)
901 m_e2_min = 0.650; //!< Minimum D2 energy deposit (MeV)
902 m_e2_max = 30.0; //!< Maximum D2 energy deposit (MeV)
903 m_tof_min = 115; //!< Minimum TOF window
904 m_tof_max = 130; //!< Maximum TOF window
905 m_psd_min = 0; //!< Minimum PSD window
906 m_psd_max = 110; //!< Maximum PSD window
907 m_reflag_min = 1; //!< Minimum rejection flag
908 m_reflag_max = 1000; //!< Maximum rejection flag
909 m_vetoflag_min = 0; //!< Minimum veto flag
910 m_vetoflag_max = 0; //!< Maximum veto flag
911 m_fpmtflag = 0; //!< D2 PMT failure flag
915 m_pulsar.clear();
916 for (int i = 0; i < 7; ++i) {
917 m_use_d1[i] = true;
918 }
919 for (int i = 0; i < 14; ++i) {
920 m_use_d2[i] = true;
921 }
922
923 // Initialise statistics
925
926 // Return
927 return;
928}
929
930
931/***********************************************************************//**
932 * @brief Copy class members
933 *
934 * @param[in] select COMPTEL selection set.
935 ***************************************************************************/
937{
938 // Copy members
939 m_e1_min = select.m_e1_min;
940 m_e1_max = select.m_e1_max;
941 m_e2_min = select.m_e2_min;
942 m_e2_max = select.m_e2_max;
943 m_tof_min = select.m_tof_min;
944 m_tof_max = select.m_tof_max;
945 m_psd_min = select.m_psd_min;
946 m_psd_max = select.m_psd_max;
947 m_reflag_min = select.m_reflag_min;
948 m_reflag_max = select.m_reflag_max;
951 m_fpmtflag = select.m_fpmtflag;
955 m_pulsar = select.m_pulsar;
956 for (int i = 0; i < 7; ++i) {
957 m_use_d1[i] = select.m_use_d1[i];
958 }
959 for (int i = 0; i < 14; ++i) {
960 m_use_d2[i] = select.m_use_d2[i];
961 }
962
963 // Copy statistics
967 m_num_e1_min = select.m_num_e1_min;
968 m_num_e1_max = select.m_num_e1_max;
969 m_num_e2_min = select.m_num_e2_min;
970 m_num_e2_max = select.m_num_e2_max;
983 m_num_fpmt = select.m_num_fpmt;
984
985 // Copy module usage
986 for (int i = 0; i < 7; ++i) {
987 m_num_d1[i] = select.m_num_d1[i];
988 }
989 for (int i = 0; i < 14; ++i) {
990 m_num_d2[i] = select.m_num_d2[i];
991 }
992
993 // Return
994 return;
995}
996
997
998/***********************************************************************//**
999 * @brief Delete class members
1000 ***************************************************************************/
1002{
1003 // Return
1004 return;
1005}
COMPTEL event atom class definition.
#define G_FPMTFLAG
#define G_USE_D2_SET
#define G_USE_D1_GET
#define G_USE_D2_GET
#define G_USE_D1_SET
COMPTEL selection set class definition.
COMPTEL instrument status class definition.
Implementation of support function used by COMPTEL classes.
Definition of COMPTEL tools.
Abstract FITS extension base class definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
COMPTEL event atom class.
void reflag(const int &reflag)
Set rejection flag.
void veto(const int &veto)
Set veto flag.
void e1(const float &e1)
Set D1 module energy deposit.
void theta(const float &theta)
Set scatter zenith angle.
void modcom(const int &modcom)
Set mini telescope.
void psd(const float &psd)
Set PSD value.
const GTime & time(void) const
Return event time.
void tof(const float &tof)
Set TOF value.
void e2(const float &e2)
Set D2 module energy deposit.
COMPTEL selection set class.
GPulsar m_pulsar
Pulsar information.
int m_num_d1module_off
Number of events excluded since D1 module off.
virtual GCOMSelection * clone(void) const
Clone COMPTEL selection set.
int m_num_d2module_off
Number of events excluded since D2 module off.
int m_tof_min
Minimum TOF window.
int m_num_reflag_min
Number of events below rejection flag threshold.
virtual ~GCOMSelection(void)
Destructor.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print COMPTEL selection set.
int m_vetoflag_max
Maximum veto flag.
GCOMSelection & operator=(const GCOMSelection &select)
Assignment operator.
GCOMSelection(void)
Void constructor.
const int & fpmtflag(void) const
Return failed PMT flag for D2 modules.
int m_num_invalid_modcom
Number of events with invalid minitelescopes.
void copy_members(const GCOMSelection &select)
Copy class members.
GModelTemporalPhaseCurve m_orbital_phase_curve
Orbital phase curve.
void read(const GFitsHDU &hdu)
Read selection set from FITS HDU keywords.
int m_num_vetoflag_max
Number of events above veto flag threshold.
double m_e2_max
Maximum D2 energy deposit (MeV)
int m_reflag_max
Maximum rejection flag.
bool m_use_d2[14]
D2 module usage.
bool m_use_d1[7]
D1 module usage.
void write(GFitsHDU &hdu) const
Write selection set keywords into FITS HDU.
bool use_event(const GCOMEventAtom &event) const
Check if event should be used.
GPhases m_orbital_phases
Phases for orbital phase selection.
void init_statistics(void) const
Initialise selection statistics.
double m_e1_min
Minimum D1 energy deposit (MeV)
void free_members(void)
Delete class members.
int m_num_reflag_max
Number of events above rejection flag threshold.
int m_vetoflag_min
Minimum veto flag.
int m_num_e1_max
Number of events above E1 threshold.
int m_num_e2_max
Number of events above E2 threshold.
int m_num_e1_min
Number of events below E1 threshold.
int m_num_psd_max
Number of events above PSD threshold.
int m_num_d2[14]
Number of events per D2 module.
int m_num_no_scatter
Number of events without scatter angle.
const bool & use_d1(const int &id1) const
Return D1 module usage flag.
const bool & use_d2(const int &id2) const
Return D2 module usage flag.
void orbital_period(const double &period, const GTime &time)
Set orbital period.
int m_psd_max
Maximum PSD window.
virtual void clear(void)
Clear COMPTEL selection set.
int m_num_events_used
Number of used events.
int m_num_e2_min
Number of events below E2 threshold.
GPhases m_pulsar_phases
Phases for pulse phase selection.
void init_members(void)
Initialise class members.
int m_reflag_min
Minimum rejection flag.
int m_num_events_checked
Number of checked events.
double m_e2_min
Minimum D2 energy deposit (MeV)
int m_num_vetoflag_min
Number of events below veto flag threshold.
int m_tof_max
Maximum TOF window.
int m_num_tof_max
Number of events above TOF threshold.
int m_num_tof_min
Number of events below TOF threshold.
double m_e1_max
Maximum D1 energy deposit (MeV)
int m_num_d1[7]
Number of events per D1 module.
int m_num_events_rejected
Number of rejected events.
int m_psd_min
Minimum PSD window.
int m_num_fpmt
Number of events excluded due to failed PMT.
int m_num_psd_min
Number of events below PSD threshold.
COMPTEL instrument status class.
int d2status(const int &tjd, const int &module) const
Return D2 module status.
int d1status(const int &tjd, const int &module) const
Return D1 module status.
Abstract FITS extension base class.
Definition GFitsHDU.hpp:51
bool has_card(const int &cardno) const
Check existence of header card.
Definition GFitsHDU.hpp:233
double real(const std::string &keyname) const
Return card value as double precision.
Definition GFitsHDU.hpp:423
std::string string(const std::string &keyname) const
Return card value as string.
Definition GFitsHDU.hpp:410
GFitsHeaderCard & card(const int &cardno)
Return header card.
Definition GFitsHDU.hpp:259
int integer(const std::string &keyname) const
Return card value as integer.
Definition GFitsHDU.hpp:436
double f1(void) const
Return first frequency derivative at reference Modified Julian Day.
double f0(void) const
Return frequency at reference Modified Julian Day.
double f2(void) const
Return second frequency derivative at reference Modified Julian Day.
virtual std::string print(const GChatter &chatter=NORMAL) const
Print phase curve information.
virtual void clear(void)
Clear phase curve.
double phase(void) const
Return phase at reference Modified Julian Day.
GTime mjd(void) const
Return reference Modified Julian Day.
std::string print(const GChatter &chatter=NORMAL) const
Print phase intervals.
Definition GPhases.cpp:386
bool is_empty(void) const
Signal if there are no phase intervals.
Definition GPhases.hpp:114
void clear(void)
Clear phase intervals.
Definition GPhases.cpp:166
virtual void clear(void)
Clear Pulsar.
Definition GPulsar.cpp:171
virtual std::string print(const GChatter &chatter=NORMAL) const
Print Pulsar.
Definition GPulsar.cpp:381
bool is_empty(void) const
Signals if there are no ephemerides for pulsar.
Definition GPulsar.hpp:164
Time class.
Definition GTime.hpp:55
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition GTools.cpp:1143
const double & com_exd2r(const int &id2)
Return D2 module exclusion region radius.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489
const double & com_exd2x(const int &id2)
Return D2 module exclusion region X position.
std::string strip_whitespace(const std::string &arg)
Strip leading and trailing whitespace from string.
Definition GTools.cpp:80
const double & com_exd2y(const int &id2)
Return D2 module exclusion region Y position.
const double sec_in_day
Definition GTools.hpp:49
int com_tjd(const GTime &time)
Convert GTime in COMPTEL TJD.
Definition GCOMTools.cpp:91