Commit d6d5c87a8e9689a6fedb822b357af9fd7f540f29

Authored by Jürgen Knödlseder
1 parent e3a95330

Allow allocation of individual CTA event bins outside an event cube

Implement the same memory management scheme that was also implemented for the COMPTEL event bin. This enables using an event bin outside an event cube.

Added extensive unit test for the event bin, including the setting of all attributes.
inst/cta/include/GCTAEventBin.hpp
... ... @@ -77,12 +77,19 @@ public:
77 77 virtual std::string print(const GChatter& chatter = NORMAL) const;
78 78  
79 79 // Other methods
  80 + const int& ipix(void) const;
  81 + const int& ieng(void) const;
80 82 const double& solidangle(void) const;
81 83 const GEnergy& ewidth(void) const;
82 84 const double& ontime(void) const;
83 85 const double& weight(void) const;
84   - const int& ipix(void) const;
85   - const int& ieng(void) const;
  86 + void dir(const GCTAInstDir& dir);
  87 + void energy(const GEnergy& energy);
  88 + void time(const GTime& time);
  89 + void solidangle(const double& solidangle);
  90 + void ewidth(const GEnergy& ewidth);
  91 + void ontime(const double& ontime);
  92 + void weight(const double& weight);
86 93  
87 94 protected:
88 95 // Protected methods
... ... @@ -91,14 +98,15 @@ protected:
91 98 void free_members(void);
92 99  
93 100 // Protected members
  101 + bool m_alloc; //!< Signals proper memory allocation
94 102 int m_ipix; //!< Index in spatial map
95 103 int m_ieng; //!< Index of energy layer
96   - GEnergy* m_energy; //!< Pointer to bin energy
97 104 GCTAInstDir* m_dir; //!< Pointer to bin direction
98 105 GTime* m_time; //!< Pointer to bin time
  106 + GEnergy* m_energy; //!< Pointer to bin energy
  107 + GEnergy* m_ewidth; //!< Pointer to energy width of bin
99 108 double* m_counts; //!< Pointer to number of counts
100 109 double* m_solidangle; //!< Pointer to solid angle of pixel (sr)
101   - GEnergy* m_ewidth; //!< Pointer to energy width of bin
102 110 double* m_ontime; //!< Pointer to ontime of bin (seconds)
103 111 double* m_weight; //!< Pointer to weight of bin
104 112 };
... ...
inst/cta/include/GCTAEventCube.hpp
... ... @@ -107,6 +107,7 @@ protected:
107 107 void set_directions(void);
108 108 virtual void set_energies(void);
109 109 virtual void set_times(void);
  110 + void init_bin(void);
110 111 void set_bin(const int& index);
111 112  
112 113 // Protected members
... ...
inst/cta/pyext/GCTAEventBin.i
... ... @@ -58,12 +58,19 @@ public:
58 58 virtual void counts(const double& counts);
59 59  
60 60 // Other methods
  61 + const int& ipix(void) const;
  62 + const int& ieng(void) const;
61 63 const double& solidangle(void) const;
62 64 const GEnergy& ewidth(void) const;
63 65 const double& ontime(void) const;
64 66 const double& weight(void) const;
65   - const int& ipix(void) const;
66   - const int& ieng(void) const;
  67 + void dir(const GCTAInstDir& dir);
  68 + void energy(const GEnergy& energy);
  69 + void time(const GTime& time);
  70 + void solidangle(const double& solidangle);
  71 + void ewidth(const GEnergy& ewidth);
  72 + void ontime(const double& ontime);
  73 + void weight(const double& weight);
67 74 };
68 75  
69 76  
... ...
inst/cta/src/GCTAEventBin.cpp
... ... @@ -35,15 +35,22 @@
35 35 #include "GTools.hpp"
36 36  
37 37 /* __ Method name definitions ____________________________________________ */
38   -#define G_DIR "GCTAEventBin::dir()"
  38 +#define G_DIR_GET "GCTAEventBin::dir()"
39 39 #define G_ENERGY "GCTAEventBin::energy()"
40 40 #define G_TIME "GCTAEventBin::time()"
41 41 #define G_COUNTS_GET "GCTAEventBin::counts()"
42   -#define G_COUNTS_SET "GCTAEventBin::counts(double&)"
43 42 #define G_SOLIDANGLE "GCTAEventBin::solidangle()"
44 43 #define G_EWIDTH "GCTAEventBin::ewidth()"
45 44 #define G_ONTIME "GCTAEventBin::ontime()"
46 45 #define G_WEIGHT "GCTAEventBin::weight()"
  46 +#define G_DIR_SET "GCTAEventBin::dir(GCTAInstDir&)"
  47 +#define G_ENERGY_SET "GCTAEventBin::energy(GEnergy&)"
  48 +#define G_TIME_SET "GCTAEventBin::time(GTime&)"
  49 +#define G_COUNTS_SET "GCTAEventBin::counts(double&)"
  50 +#define G_SOLIDANGLE_SET "GCTAEventBin::solidangle(double&)"
  51 +#define G_EWIDTH_SET "GCTAEventBin::ewidth(GEnergy&)"
  52 +#define G_ONTIME_SET "GCTAEventBin::ontime(double&)"
  53 +#define G_WEIGHT_SET "GCTAEventBin::weight(double&)"
47 54  
48 55 /* __ Macros _____________________________________________________________ */
49 56  
... ... @@ -201,7 +208,7 @@ double GCTAEventBin::size(void) const
201 208 *
202 209 * @return Instrument direction of event bin
203 210 *
204   - * @exception GCTAException::no_member
  211 + * @exception GException::invalid_value
205 212 * Invalid instrument direction pointer.
206 213 *
207 214 * Returns reference to the instrument direction of the event bin.
... ... @@ -210,8 +217,8 @@ const GCTAInstDir&amp; GCTAEventBin::dir(void) const
210 217 {
211 218 // Throw an exception if instrument direction pointer is not valid
212 219 if (m_dir == NULL) {
213   - throw GCTAException::no_member(G_DIR,
214   - "Invalid instrument direction pointer.");
  220 + std::string msg = "No valid instrument direction found in event bin";
  221 + throw GException::invalid_value(G_DIR_GET, msg);
215 222 }
216 223  
217 224 // Return instrument direction
... ... @@ -224,7 +231,7 @@ const GCTAInstDir&amp; GCTAEventBin::dir(void) const
224 231 *
225 232 * @return Energy of event bin
226 233 *
227   - * @exception GCTAException::no_member
  234 + * @exception GException::invalid_value
228 235 * Invalid energy pointer.
229 236 *
230 237 * Returns reference to the energy of the event bin.
... ... @@ -233,8 +240,8 @@ const GEnergy&amp; GCTAEventBin::energy(void) const
233 240 {
234 241 // Throw an exception if energy pointer is not valid
235 242 if (m_energy == NULL) {
236   - throw GCTAException::no_member(G_ENERGY,
237   - "Invalid energy pointer.");
  243 + std::string msg = "No valid energy found in event bin";
  244 + throw GException::invalid_value(G_ENERGY, msg);
238 245 }
239 246  
240 247 // Return energy
... ... @@ -247,7 +254,7 @@ const GEnergy&amp; GCTAEventBin::energy(void) const
247 254 *
248 255 * @return Time of event bin
249 256 *
250   - * @exception GCTAException::no_member
  257 + * @exception GException::invalid_value
251 258 * Invalid time pointer.
252 259 *
253 260 * Returns reference to the time of the event bin.
... ... @@ -255,9 +262,9 @@ const GEnergy&amp; GCTAEventBin::energy(void) const
255 262 const GTime& GCTAEventBin::time(void) const
256 263 {
257 264 // Throw an exception if time pointer is not valid
258   - if (m_time == NULL) {
259   - throw GCTAException::no_member(G_TIME,
260   - "Invalid time pointer.");
  265 + if (m_energy == NULL) {
  266 + std::string msg = "No valid time found in event bin";
  267 + throw GException::invalid_value(G_TIME, msg);
261 268 }
262 269  
263 270 // Return time
... ... @@ -279,8 +286,8 @@ double GCTAEventBin::counts(void) const
279 286 {
280 287 // Throw an exception if counts pointer is not valid
281 288 if (m_counts == NULL) {
282   - throw GCTAException::no_member(G_COUNTS_GET,
283   - "Invalid counts pointer.");
  289 + std::string msg = "No valid counts found in event bin";
  290 + throw GException::invalid_value(G_COUNTS_GET, msg);
284 291 }
285 292  
286 293 // Return counts
... ... @@ -289,32 +296,6 @@ double GCTAEventBin::counts(void) const
289 296  
290 297  
291 298 /***********************************************************************//**
292   - * @brief Set number of counts in event bin
293   - *
294   - * @param[in] counts Number of counts.
295   - *
296   - * @exception GCTAException::no_member
297   - * Invalid counts pointer.
298   - *
299   - * Set the number of counts in the event bin.
300   - ***************************************************************************/
301   -void GCTAEventBin::counts(const double& counts)
302   -{
303   - // Throw an exception if counts pointer is not valid
304   - if (m_counts == NULL) {
305   - throw GCTAException::no_member(G_COUNTS_SET,
306   - "Invalid counts pointer.");
307   - }
308   -
309   - // Set number of counts in event bin
310   - *m_counts = counts;
311   -
312   - // Return
313   - return;
314   -}
315   -
316   -
317   -/***********************************************************************//**
318 299 * @brief Return error in number of counts
319 300 *
320 301 * @return Error in number of counts in event bin
... ... @@ -342,17 +323,17 @@ double GCTAEventBin::error(void) const
342 323 *
343 324 * @return Solid angle of event bin
344 325 *
345   - * @exception GCTAException::no_member
  326 + * @exception GException::invalid_value
346 327 * Invalid solid angle pointer.
347 328 *
348 329 * Returns reference to the solid angle of the event bin.
349 330 ***************************************************************************/
350 331 const double& GCTAEventBin::solidangle(void) const
351 332 {
352   - // Throw an exception if solid angle pointer is not valid
  333 + // Throw an exception if counts pointer is not valid
353 334 if (m_solidangle == NULL) {
354   - throw GCTAException::no_member(G_SOLIDANGLE,
355   - "Invalid solid angle pointer.");
  335 + std::string msg = "No valid solid angle found in event bin";
  336 + throw GException::invalid_value(G_SOLIDANGLE, msg);
356 337 }
357 338  
358 339 // Return solid angle
... ... @@ -365,7 +346,7 @@ const double&amp; GCTAEventBin::solidangle(void) const
365 346 *
366 347 * @return Energy width of event bin
367 348 *
368   - * @exception GCTAException::no_member
  349 + * @exception GException::invalid_value
369 350 * Invalid energy width pointer.
370 351 *
371 352 * Returns reference to the energy width of the event bin.
... ... @@ -374,8 +355,8 @@ const GEnergy&amp; GCTAEventBin::ewidth(void) const
374 355 {
375 356 // Throw an exception if energy width pointer is not valid
376 357 if (m_ewidth == NULL) {
377   - throw GCTAException::no_member(G_EWIDTH,
378   - "Invalid energy width pointer.");
  358 + std::string msg = "No valid energy width found in event bin";
  359 + throw GException::invalid_value(G_EWIDTH, msg);
379 360 }
380 361  
381 362 // Return energy width
... ... @@ -388,17 +369,17 @@ const GEnergy&amp; GCTAEventBin::ewidth(void) const
388 369 *
389 370 * @return Ontime of event bin
390 371 *
391   - * @exception GCTAException::no_member
  372 + * @exception GException::invalid_value
392 373 * Invalid ontime pointer.
393 374 *
394 375 * Returns reference to the ontime of the event bin.
395 376 ***************************************************************************/
396 377 const double& GCTAEventBin::ontime(void) const
397 378 {
398   - // Throw an exception if ontime pointer is not valid
  379 + // Throw an exception if energy width pointer is not valid
399 380 if (m_ontime == NULL) {
400   - throw GCTAException::no_member(G_ONTIME,
401   - "Invalid ontime pointer.");
  381 + std::string msg = "No valid ontime found in event bin";
  382 + throw GException::invalid_value(G_ONTIME, msg);
402 383 }
403 384  
404 385 // Return ontime
... ... @@ -411,7 +392,7 @@ const double&amp; GCTAEventBin::ontime(void) const
411 392 *
412 393 * @return Weight of event bin
413 394 *
414   - * @exception GCTAException::no_member
  395 + * @exception GException::invalid_value
415 396 * Invalid weight pointer.
416 397 *
417 398 * Returns reference to the weight of the event bin.
... ... @@ -420,8 +401,8 @@ const double&amp; GCTAEventBin::weight(void) const
420 401 {
421 402 // Throw an exception if weight pointer is not valid
422 403 if (m_weight == NULL) {
423   - throw GCTAException::no_member(G_WEIGHT,
424   - "Invalid weight pointer.");
  404 + std::string msg = "No valid weight found in event bin";
  405 + throw GException::invalid_value(G_WEIGHT, msg);
425 406 }
426 407  
427 408 // Return weight
... ... @@ -430,6 +411,214 @@ const double&amp; GCTAEventBin::weight(void) const
430 411  
431 412  
432 413 /***********************************************************************//**
  414 + * @brief Set instrument direction of event bin
  415 + *
  416 + * @param[in] dir Instrument direction of event bin
  417 + *
  418 + * @exception GException::invalid_value
  419 + * No memory available to hold instrument direction.
  420 + *
  421 + * Sets the instrument direction of the event bin.
  422 + ***************************************************************************/
  423 +void GCTAEventBin::dir(const GCTAInstDir& dir)
  424 +{
  425 + // Throw an exception if no memory has been allocated
  426 + if (m_dir == NULL) {
  427 + std::string msg = "No memory available to hold instrument direction.";
  428 + throw GException::invalid_value(G_DIR_SET, msg);
  429 + }
  430 +
  431 + // Set instrument direction
  432 + *m_dir = dir;
  433 +
  434 + // Return
  435 + return;
  436 +}
  437 +
  438 +
  439 +/***********************************************************************//**
  440 + * @brief Set energy of event bin
  441 + *
  442 + * @param[in] energy Energy of event bin
  443 + *
  444 + * @exception GException::invalid_value
  445 + * No memory available to hold energy.
  446 + *
  447 + * Sets the energy of the event bin.
  448 + ***************************************************************************/
  449 +void GCTAEventBin::energy(const GEnergy& energy)
  450 +{
  451 + // Throw an exception if no memory has been allocated
  452 + if (m_energy == NULL) {
  453 + std::string msg = "No memory available to hold energy.";
  454 + throw GException::invalid_value(G_ENERGY_SET, msg);
  455 + }
  456 +
  457 + // Set energy
  458 + *m_energy = energy;
  459 +
  460 + // Return
  461 + return;
  462 +}
  463 +
  464 +
  465 +/***********************************************************************//**
  466 + * @brief Set time of event bin
  467 + *
  468 + * @param[in] time Time of event bin
  469 + *
  470 + * @exception GException::invalid_value
  471 + * No memory available to hold instrument direction.
  472 + *
  473 + * Sets the time of the event bin.
  474 + ***************************************************************************/
  475 +void GCTAEventBin::time(const GTime& time)
  476 +{
  477 + // Throw an exception if no memory has been allocated
  478 + if (m_time == NULL) {
  479 + std::string msg = "No memory available to hold time.";
  480 + throw GException::invalid_value(G_TIME_SET, msg);
  481 + }
  482 +
  483 + // Set time
  484 + *m_time = time;
  485 +
  486 + // Return
  487 + return;
  488 +}
  489 +
  490 +
  491 +/***********************************************************************//**
  492 + * @brief Set number of counts in event bin
  493 + *
  494 + * @param[in] counts Number of counts.
  495 + *
  496 + * @exception GException::invalid_value
  497 + * No memory available to hold counts.
  498 + *
  499 + * Set the number of counts in the event bin.
  500 + ***************************************************************************/
  501 +void GCTAEventBin::counts(const double& counts)
  502 +{
  503 + // Throw an exception if counts pointer is not valid
  504 + if (m_counts == NULL) {
  505 + std::string msg = "No memory available to hold counts.";
  506 + throw GException::invalid_value(G_COUNTS_SET, msg);
  507 + }
  508 +
  509 + // Set number of counts in event bin
  510 + *m_counts = counts;
  511 +
  512 + // Return
  513 + return;
  514 +}
  515 +
  516 +
  517 +/***********************************************************************//**
  518 + * @brief Set solid angle of event bin
  519 + *
  520 + * @param[in] solidangle Solid angle of event bin
  521 + *
  522 + * @exception GException::invalid_value
  523 + * No memory available to hold solid angle.
  524 + *
  525 + * Sets the solid angle of the event bin.
  526 + ***************************************************************************/
  527 +void GCTAEventBin::solidangle(const double& solidangle)
  528 +{
  529 + // Throw an exception if no memory has been allocated
  530 + if (m_solidangle == NULL) {
  531 + std::string msg = "No memory available to hold solid angle.";
  532 + throw GException::invalid_value(G_SOLIDANGLE_SET, msg);
  533 + }
  534 +
  535 + // Set solid angle
  536 + *m_solidangle = solidangle;
  537 +
  538 + // Return
  539 + return;
  540 +}
  541 +
  542 +
  543 +/***********************************************************************//**
  544 + * @brief Set energy width of event bin
  545 + *
  546 + * @param[in] ewidth Energy width of event bin
  547 + *
  548 + * @exception GException::invalid_value
  549 + * No memory available to hold energy width.
  550 + *
  551 + * Sets the energy width of the event bin.
  552 + ***************************************************************************/
  553 +void GCTAEventBin::ewidth(const GEnergy& ewidth)
  554 +{
  555 + // Throw an exception if no memory has been allocated
  556 + if (m_ewidth == NULL) {
  557 + std::string msg = "No memory available to hold energy width.";
  558 + throw GException::invalid_value(G_EWIDTH_SET, msg);
  559 + }
  560 +
  561 + // Set energy width
  562 + *m_ewidth = ewidth;
  563 +
  564 + // Return
  565 + return;
  566 +}
  567 +
  568 +
  569 +/***********************************************************************//**
  570 + * @brief Set ontime of event bin
  571 + *
  572 + * @param[in] ontime Ontime of event bin (sec).
  573 + *
  574 + * @exception GException::invalid_value
  575 + * No memory available to hold ontime.
  576 + *
  577 + * Sets the ontime of the event bin.
  578 + ***************************************************************************/
  579 +void GCTAEventBin::ontime(const double& ontime)
  580 +{
  581 + // Throw an exception if no memory has been allocated
  582 + if (m_ontime == NULL) {
  583 + std::string msg = "No memory available to hold ontime.";
  584 + throw GException::invalid_value(G_ONTIME_SET, msg);
  585 + }
  586 +
  587 + // Set solid angle
  588 + *m_ontime = ontime;
  589 +
  590 + // Return
  591 + return;
  592 +}
  593 +
  594 +
  595 +/***********************************************************************//**
  596 + * @brief Set weight of event bin
  597 + *
  598 + * @param[in] weight Weight angle of event bin
  599 + *
  600 + * @exception GException::invalid_value
  601 + * No memory available to hold weight.
  602 + *
  603 + * Sets the weight of the event bin.
  604 + ***************************************************************************/
  605 +void GCTAEventBin::weight(const double& weight)
  606 +{
  607 + // Throw an exception if no memory has been allocated
  608 + if (m_weight == NULL) {
  609 + std::string msg = "No memory available to hold weight.";
  610 + throw GException::invalid_value(G_WEIGHT_SET, msg);
  611 + }
  612 +
  613 + // Set weight
  614 + *m_weight = weight;
  615 +
  616 + // Return
  617 + return;
  618 +}
  619 +
  620 +
  621 +/***********************************************************************//**
433 622 * @brief Print event information
434 623 *
435 624 * @param[in] chatter Chattiness (defaults to NORMAL).
... ... @@ -461,20 +650,36 @@ std::string GCTAEventBin::print(const GChatter&amp; chatter) const
461 650  
462 651 /***********************************************************************//**
463 652 * @brief Initialise class members
  653 + *
  654 + * This method allocates memory for all event bin attributes and intialises
  655 + * the attributes to well defined initial values.
  656 + *
  657 + * The method assumes that on entry no memory is hold by the member pointers.
464 658 ***************************************************************************/
465 659 void GCTAEventBin::init_members(void)
466 660 {
467 661 // Initialise members
  662 + m_alloc = true;
468 663 m_ipix = -1; //!< Not part of an event cube
469 664 m_ieng = -1; //!< Not part of an event cube
470   - m_energy = NULL;
471   - m_dir = NULL;
472   - m_time = NULL;
473   - m_counts = NULL;
474   - m_solidangle = NULL;
475   - m_ewidth = NULL;
476   - m_ontime = NULL;
477   - m_weight = NULL;
  665 + m_dir = new GCTAInstDir;
  666 + m_time = new GTime;
  667 + m_energy = new GEnergy;
  668 + m_ewidth = new GEnergy;
  669 + m_counts = new double;
  670 + m_solidangle = new double;
  671 + m_ontime = new double;
  672 + m_weight = new double;
  673 +
  674 + // Initialise members
  675 + m_dir->clear();
  676 + m_time->clear();
  677 + m_energy->clear();
  678 + m_ewidth->clear();
  679 + *m_counts = 0.0;
  680 + *m_solidangle = 0.0;
  681 + *m_ontime = 0.0;
  682 + *m_weight = 0.0;
478 683  
479 684 // Return
480 685 return;
... ... @@ -488,17 +693,25 @@ void GCTAEventBin::init_members(void)
488 693 ***************************************************************************/
489 694 void GCTAEventBin::copy_members(const GCTAEventBin& bin)
490 695 {
491   - // Copy members
492   - m_ipix = bin.m_ipix;
493   - m_ieng = bin.m_ieng;
494   - m_energy = bin.m_energy;
495   - m_dir = bin.m_dir;
496   - m_time = bin.m_time;
497   - m_counts = bin.m_counts;
498   - m_solidangle = bin.m_solidangle;
499   - m_ewidth = bin.m_ewidth;
500   - m_ontime = bin.m_ontime;
501   - m_weight = bin.m_weight;
  696 + // First de-allocate existing memory if needed
  697 + free_members();
  698 +
  699 + // Copy members by cloning
  700 + m_dir = new GCTAInstDir(*bin.m_dir);
  701 + m_time = new GTime(*bin.m_time);
  702 + m_energy = new GEnergy(*bin.m_energy);
  703 + m_ewidth = new GEnergy(*bin.m_ewidth);
  704 + m_counts = new double(*bin.m_counts);
  705 + m_solidangle = new double(*bin.m_solidangle);
  706 + m_ontime = new double(*bin.m_ontime);
  707 + m_weight = new double(*bin.m_weight);
  708 +
  709 + // Copy non-pointer members
  710 + m_ipix = bin.m_ipix;
  711 + m_ieng = bin.m_ieng;
  712 +
  713 + // Signal memory allocation
  714 + m_alloc = true;
502 715  
503 716 // Return
504 717 return;
... ... @@ -507,9 +720,44 @@ void GCTAEventBin::copy_members(const GCTAEventBin&amp; bin)
507 720  
508 721 /***********************************************************************//**
509 722 * @brief Delete class members
  723 + *
  724 + * This method frees all memory of the class attributes and sets the member
  725 + * pointers to NULL. This method should only be called if new memory is
  726 + * allocated immediately afterwards (for example by cloning another event
  727 + * bin), or upon destruction of the object.
  728 + *
  729 + * Note that some logic has been implemented that frees only memory that also
  730 + * has indeed been allocated by the class. Thus if the class only serves as
  731 + * container to hold memory pointer allocated by someone else (for example
  732 + * the GCTAEventCube class), no memory is freed.
510 733 ***************************************************************************/
511 734 void GCTAEventBin::free_members(void)
512 735 {
  736 + // If memory was allocated then free members now
  737 + if (m_alloc) {
  738 + if (m_dir != NULL) delete m_dir;
  739 + if (m_time != NULL) delete m_time;
  740 + if (m_energy != NULL) delete m_energy;
  741 + if (m_ewidth != NULL) delete m_ewidth;
  742 + if (m_counts != NULL) delete m_counts;
  743 + if (m_solidangle != NULL) delete m_solidangle;
  744 + if (m_ontime != NULL) delete m_ontime;
  745 + if (m_weight != NULL) delete m_weight;
  746 + }
  747 +
  748 + // Signal member pointers as free
  749 + m_dir = NULL;
  750 + m_time = NULL;
  751 + m_energy = NULL;
  752 + m_ewidth = NULL;
  753 + m_counts = NULL;
  754 + m_solidangle = NULL;
  755 + m_ontime = NULL;
  756 + m_weight = NULL;
  757 +
  758 + // Signal memory de-allocation
  759 + m_alloc = false;
  760 +
513 761 // Return
514 762 return;
515 763 }
... ...
inst/cta/src/GCTAEventCube.cpp
... ... @@ -696,6 +696,9 @@ void GCTAEventCube::init_members(void)
696 696 m_ewidth.clear();
697 697 m_ontime = 0.0;
698 698  
  699 + // Prepare event bin
  700 + init_bin();
  701 +
699 702 // Return
700 703 return;
701 704 }
... ... @@ -705,13 +708,20 @@ void GCTAEventCube::init_members(void)
705 708 * @brief Copy class members
706 709 *
707 710 * @param[in] cube Event cube.
  711 + *
  712 + * This method copies the class members from another event cube in the actual
  713 + * object. It also prepares the event bin member that will be returned in
  714 + * case of an operator access to the class.
708 715 ***************************************************************************/
709 716 void GCTAEventCube::copy_members(const GCTAEventCube& cube)
710 717 {
711   - // Copy members
  718 + // Copy members. Note that the event bin is not copied as it will
  719 + // be initialised later. The event bin serves just as a container of
  720 + // pointers, hence we do not want to copy over the pointers from the
  721 + // original class.
712 722 m_map = cube.m_map;
713 723 m_weights = cube.m_weights;
714   - m_bin = cube.m_bin;
  724 + //m_bin = cube.m_bin;
715 725 m_time = cube.m_time;
716 726 m_dirs = cube.m_dirs;
717 727 m_solidangle = cube.m_solidangle;
... ... @@ -719,6 +729,9 @@ void GCTAEventCube::copy_members(const GCTAEventCube&amp; cube)
719 729 m_ewidth = cube.m_ewidth;
720 730 m_ontime = cube.m_ontime;
721 731  
  732 + // Prepare event bin
  733 + init_bin();
  734 +
722 735 // Return
723 736 return;
724 737 }
... ... @@ -924,6 +937,26 @@ void GCTAEventCube::set_times(void)
924 937  
925 938  
926 939 /***********************************************************************//**
  940 + * @brief Initialise event bin
  941 + *
  942 + * This method initialises the event bin. The event bin is cleared and all
  943 + * fixed pointers are set.
  944 + ***************************************************************************/
  945 +void GCTAEventCube::init_bin(void)
  946 +{
  947 + // Free any existing memory
  948 + m_bin.free_members();
  949 +
  950 + // Set fixed pointers (those will not be set in set_bin)
  951 + m_bin.m_time = &m_time;
  952 + m_bin.m_ontime = &m_ontime;
  953 +
  954 + // Return
  955 + return;
  956 +}
  957 +
  958 +
  959 +/***********************************************************************//**
927 960 * @brief Set event bin
928 961 *
929 962 * @param[in] index Event index [0,...,size()-1].
... ... @@ -967,11 +1000,11 @@ void GCTAEventCube::set_bin(const int&amp; index)
967 1000 // Set pointers
968 1001 m_bin.m_counts = const_cast<double*>(&(m_map.pixels()[index]));
969 1002 m_bin.m_energy = &(m_energies[m_bin.m_ieng]);
970   - m_bin.m_time = &m_time;
  1003 + //m_bin.m_time = &m_time;
971 1004 m_bin.m_dir = &(m_dirs[m_bin.m_ipix]);
972 1005 m_bin.m_solidangle = &(m_solidangle[m_bin.m_ipix]);
973 1006 m_bin.m_ewidth = &(m_ewidth[m_bin.m_ieng]);
974   - m_bin.m_ontime = &m_ontime;
  1007 + //m_bin.m_ontime = &m_ontime;
975 1008 m_bin.m_weight = const_cast<double*>(&(m_weights.pixels()[index]));
976 1009  
977 1010 // Return
... ...
inst/cta/test/test_CTA.cpp
... ... @@ -185,6 +185,8 @@ void TestGCTAObservation::set(void)
185 185 name("GCTAObservation");
186 186  
187 187 // Append tests to test suite
  188 + append(static_cast<pfunction>(&TestGCTAObservation::test_event_bin),
  189 + "Test event bin");
188 190 append(static_cast<pfunction>(&TestGCTAObservation::test_event_cube),
189 191 "Test event cube");
190 192 append(static_cast<pfunction>(&TestGCTAObservation::test_unbinned_obs),
... ... @@ -1439,6 +1441,187 @@ void TestGCTAModel::test_model_aeff_bgd(void)
1439 1441  
1440 1442  
1441 1443 /***********************************************************************//**
  1444 + * @brief Checks handling of CTA event bin
  1445 + ***************************************************************************/
  1446 +void TestGCTAObservation::test_event_bin(void)
  1447 +{
  1448 + // Test event bin void constructor
  1449 + GCTAEventBin bin;
  1450 + test_value(bin.classname(), "GCTAEventBin",
  1451 + "Check classname() for empty bin");
  1452 + test_value(bin.size(), 0.0, 1.0e-10, "Check size() for empty bin");
  1453 + test_value(bin.dir().dir().ra_deg(), 0.0, 1.0e-10,
  1454 + "Check dir().dir().ra_deg() for empty bin");
  1455 + test_value(bin.dir().dir().dec_deg(), 0.0, 1.0e-10,
  1456 + "Check dir().dir().dec_deg() for empty bin");
  1457 + test_value(bin.energy().MeV(), 0.0, 1.0e-10,
  1458 + "Check energy() for empty bin");
  1459 + test_value(bin.time().secs(), 0.0, 1.0e-10, "Check time() for empty bin");
  1460 + test_value(bin.counts(), 0.0, 1.0e-10, "Check counts() for empty bin");
  1461 + test_value(bin.error(), 0.0, 1.0e-10, "Check error() for empty bin");
  1462 + test_value(bin.ipix(), -1, "Check ipix() for empty bin");
  1463 + test_value(bin.ieng(), -1, "Check ieng() for empty bin");
  1464 + test_value(bin.solidangle(), 0.0, 1.0e-10,
  1465 + "Check solidangle() for empty bin");
  1466 + test_value(bin.ewidth().MeV(), 0.0, 1.0e-10,
  1467 + "Check ewidth() for empty bin");
  1468 + test_value(bin.ontime(), 0.0, 1.0e-10, "Check ontime() for empty bin");
  1469 + test_value(bin.weight(), 0.0, 1.0e-10, "Check weight() for empty bin");
  1470 + test_value(bin.print(), "0", "Check print() for empty bin");
  1471 +
  1472 + // Set bin attributes
  1473 + GSkyDir skydir;
  1474 + skydir.radec_deg(37.2, -67.3);
  1475 + GCTAInstDir instdir(skydir);
  1476 + instdir.detx(-0.78);
  1477 + instdir.dety(+0.35);
  1478 + bin.dir(instdir);
  1479 + bin.energy(GEnergy(2.0, "TeV"));
  1480 + bin.time(GTime(87.3));
  1481 + bin.counts(4.0);
  1482 + bin.solidangle(3.14);
  1483 + bin.ewidth(GEnergy(7.0, "GeV"));
  1484 + bin.ontime(101.0);
  1485 + bin.weight(0.71);
  1486 +
  1487 + // Set size reference
  1488 + double ref_size = 3.14 * 7000.0 * 101.0 * 0.71;
  1489 +
  1490 + // Test bin attributes
  1491 + test_value(bin.size(), ref_size, 1.0e-10, "Check size() for filled bin");
  1492 + test_value(bin.dir().dir().ra_deg(), 37.2, 1.0e-10,
  1493 + "Check dir().dir().ra_deg() for filled bin");
  1494 + test_value(bin.dir().dir().dec_deg(), -67.3, 1.0e-10,
  1495 + "Check dir().dir().dec_deg() for filled bin");
  1496 + test_value(bin.dir().detx(), -0.78, 1.0e-10,
  1497 + "Check dir().detx() for filled bin");
  1498 + test_value(bin.dir().dety(), +0.35, 1.0e-10,
  1499 + "Check dir().detx() for filled bin");
  1500 + test_value(bin.energy().TeV(), 2.0, 1.0e-10,
  1501 + "Check energy() for filled bin");
  1502 + test_value(bin.time().secs(), 87.3, 1.0e-10, "Check time() for filled bin");
  1503 + test_value(bin.counts(), 4.0, 1.0e-10, "Check counts() for filled bin");
  1504 + test_value(bin.error(), 2.0, 1.0e-10, "Check error() for filled bin");
  1505 + test_value(bin.ipix(), -1, "Check ipix() for filled bin");
  1506 + test_value(bin.ieng(), -1, "Check ieng() for filled bin");
  1507 + test_value(bin.solidangle(), 3.14, 1.0e-10,
  1508 + "Check solidangle() for filled bin");
  1509 + test_value(bin.ewidth().GeV(), 7.0, 1.0e-10,
  1510 + "Check ewidth() for filled bin");
  1511 + test_value(bin.ontime(), 101.0, 1.0e-10, "Check ontime() for filled bin");
  1512 + test_value(bin.weight(), 0.71, 1.0e-10, "Check weight() for filled bin");
  1513 + test_value(bin.print(), "4", "Check print() for filled bin");
  1514 +
  1515 + // Test copy constructor
  1516 + GCTAEventBin bin2(bin);
  1517 + test_value(bin2.size(), ref_size, 1.0e-10, "Check size() for copied bin");
  1518 + test_value(bin2.dir().dir().ra_deg(), 37.2, 1.0e-10,
  1519 + "Check dir().dir().ra_deg() for filled bin");
  1520 + test_value(bin2.dir().dir().dec_deg(), -67.3, 1.0e-10,
  1521 + "Check dir().dir().dec_deg() for filled bin");
  1522 + test_value(bin2.dir().detx(), -0.78, 1.0e-10,
  1523 + "Check dir().detx() for filled bin");
  1524 + test_value(bin2.dir().dety(), +0.35, 1.0e-10,
  1525 + "Check dir().detx() for filled bin");
  1526 + test_value(bin2.energy().TeV(), 2.0, 1.0e-10,
  1527 + "Check energy() for copied bin");
  1528 + test_value(bin2.time().secs(), 87.3, 1.0e-10, "Check time() for copied bin");
  1529 + test_value(bin2.counts(), 4.0, 1.0e-10, "Check counts() for copied bin");
  1530 + test_value(bin2.error(), 2.0, 1.0e-10, "Check error() for copied bin");
  1531 + test_value(bin2.ipix(), -1, "Check ipix() for copied bin");
  1532 + test_value(bin2.ieng(), -1, "Check ieng() for copied bin");
  1533 + test_value(bin2.solidangle(), 3.14, 1.0e-10,
  1534 + "Check solidangle() for copied bin");
  1535 + test_value(bin2.ewidth().GeV(), 7.0, 1.0e-10,
  1536 + "Check ewidth() for copied bin");
  1537 + test_value(bin2.ontime(), 101.0, 1.0e-10, "Check ontime() for copied bin");
  1538 + test_value(bin2.weight(), 0.71, 1.0e-10, "Check weight() for copied bin");
  1539 + test_value(bin2.print(), "4", "Check print() for copied bin");
  1540 +
  1541 + // Assignment operator
  1542 + GCTAEventBin bin3 = bin;
  1543 + test_value(bin3.size(), ref_size, 1.0e-10, "Check size() for assigned bin");
  1544 + test_value(bin3.dir().dir().ra_deg(), 37.2, 1.0e-10,
  1545 + "Check dir().dir().ra_deg() for filled bin");
  1546 + test_value(bin3.dir().dir().dec_deg(), -67.3, 1.0e-10,
  1547 + "Check dir().dir().dec_deg() for filled bin");
  1548 + test_value(bin3.dir().detx(), -0.78, 1.0e-10,
  1549 + "Check dir().detx() for filled bin");
  1550 + test_value(bin3.dir().dety(), +0.35, 1.0e-10,
  1551 + "Check dir().detx() for filled bin");
  1552 + test_value(bin3.energy().TeV(), 2.0, 1.0e-10,
  1553 + "Check energy() for assigned bin");
  1554 + test_value(bin3.time().secs(), 87.3, 1.0e-10,
  1555 + "Check time() for assigned bin");
  1556 + test_value(bin3.counts(), 4.0, 1.0e-10, "Check counts() for assigned bin");
  1557 + test_value(bin3.error(), 2.0, 1.0e-10, "Check error() for assigned bin");
  1558 + test_value(bin3.ipix(), -1, "Check ipix() for assigned bin");
  1559 + test_value(bin3.ieng(), -1, "Check ieng() for assigned bin");
  1560 + test_value(bin3.solidangle(), 3.14, 1.0e-10,
  1561 + "Check solidangle() for assigned bin");
  1562 + test_value(bin3.ewidth().GeV(), 7.0, 1.0e-10,
  1563 + "Check ewidth() for assigned bin");
  1564 + test_value(bin3.ontime(), 101.0, 1.0e-10, "Check ontime() for assigned bin");
  1565 + test_value(bin3.weight(), 0.71, 1.0e-10, "Check weight() for assigned bin");
  1566 + test_value(bin3.print(), "4", "Check print() for assigned bin");
  1567 +
  1568 + // clone method
  1569 + GCTAEventBin* bin4 = bin.clone();
  1570 + test_value(bin4->size(), ref_size, 1.0e-10, "Check size() for cloned bin");
  1571 + test_value(bin4->dir().dir().ra_deg(), 37.2, 1.0e-10,
  1572 + "Check dir().dir().ra_deg() for filled bin");
  1573 + test_value(bin4->dir().dir().dec_deg(), -67.3, 1.0e-10,
  1574 + "Check dir().dir().dec_deg() for filled bin");
  1575 + test_value(bin4->dir().detx(), -0.78, 1.0e-10,
  1576 + "Check dir().detx() for filled bin");
  1577 + test_value(bin4->dir().dety(), +0.35, 1.0e-10,
  1578 + "Check dir().detx() for filled bin");
  1579 + test_value(bin4->energy().TeV(), 2.0, 1.0e-10,
  1580 + "Check energy() for cloned bin");
  1581 + test_value(bin4->time().secs(), 87.3, 1.0e-10,
  1582 + "Check time() for cloned bin");
  1583 + test_value(bin4->counts(), 4.0, 1.0e-10, "Check counts() for cloned bin");
  1584 + test_value(bin4->error(), 2.0, 1.0e-10, "Check error() for cloned bin");
  1585 + test_value(bin4->ipix(), -1, "Check ipix() for cloned bin");
  1586 + test_value(bin4->ieng(), -1, "Check ieng() for cloned bin");
  1587 + test_value(bin4->solidangle(), 3.14, 1.0e-10,
  1588 + "Check solidangle() for cloned bin");
  1589 + test_value(bin4->ewidth().GeV(), 7.0, 1.0e-10,
  1590 + "Check ewidth() for cloned bin");
  1591 + test_value(bin4->ontime(), 101.0, 1.0e-10, "Check ontime() for cloned bin");
  1592 + test_value(bin4->weight(), 0.71, 1.0e-10, "Check weight() for cloned bin");
  1593 + test_value(bin4->print(), "4", "Check print() for cloned bin");
  1594 +
  1595 + // clear method
  1596 + bin.clear();
  1597 + test_value(bin.classname(), "GCTAEventBin",
  1598 + "Check classname() for cleared bin");
  1599 + test_value(bin.size(), 0.0, 1.0e-10, "Check size() for cleared bin");
  1600 + test_value(bin.dir().dir().ra_deg(), 0.0, 1.0e-10,
  1601 + "Check dir().dir().ra_deg() for cleared bin");
  1602 + test_value(bin.dir().dir().dec_deg(), 0.0, 1.0e-10,
  1603 + "Check dir().dir().dec_deg() for cleared bin");
  1604 + test_value(bin.energy().MeV(), 0.0, 1.0e-10,
  1605 + "Check energy() for cleared bin");
  1606 + test_value(bin.time().secs(), 0.0, 1.0e-10, "Check time() for cleared bin");
  1607 + test_value(bin.counts(), 0.0, 1.0e-10, "Check counts() for cleared bin");
  1608 + test_value(bin.error(), 0.0, 1.0e-10, "Check error() for cleared bin");
  1609 + test_value(bin.ipix(), -1, "Check ipix() for cleared bin");
  1610 + test_value(bin.ieng(), -1, "Check ieng() for cleared bin");
  1611 + test_value(bin.solidangle(), 0.0, 1.0e-10,
  1612 + "Check solidangle() for cleared bin");
  1613 + test_value(bin.ewidth().MeV(), 0.0, 1.0e-10,
  1614 + "Check ewidth() for cleared bin");
  1615 + test_value(bin.ontime(), 0.0, 1.0e-10, "Check ontime() for cleared bin");
  1616 + test_value(bin.weight(), 0.0, 1.0e-10, "Check weight() for cleared bin");
  1617 + test_value(bin.print(), "0", "Check print() for cleared bin");
  1618 +
  1619 + // Return
  1620 + return;
  1621 +}
  1622 +
  1623 +
  1624 +/***********************************************************************//**
1442 1625 * @brief Test event cube
1443 1626 ***************************************************************************/
1444 1627 void TestGCTAObservation::test_event_cube(void)
... ...
inst/cta/test/test_CTA.hpp
... ... @@ -115,6 +115,7 @@ public:
115 115 virtual void set(void);
116 116 virtual TestGCTAObservation* clone(void) const;
117 117 virtual std::string classname(void) const { return "TestGCTAObservation"; }
  118 + void test_event_bin(void);
118 119 void test_event_cube(void);
119 120 void test_unbinned_obs(void);
120 121 void test_binned_obs(void);
... ...