Commit d33e30aabadddd8d73c13b7d0d519599442d5673
Merge branch 'faster-ctbin' into bugfix-1.7.1
Showing
2 changed files
with
45 additions
and
64 deletions
src/ctbin/ctbin.cpp
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * ctbin - Event binning tool * | 2 | * ctbin - Event binning tool * |
| 3 | * ----------------------------------------------------------------------- * | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2010-2018 by Juergen Knoedlseder * | 4 | + * copyright (C) 2010-2020 by Juergen Knoedlseder * |
| 5 | * ----------------------------------------------------------------------- * | 5 | * ----------------------------------------------------------------------- * |
| 6 | * * | 6 | * * |
| 7 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -89,7 +89,6 @@ ctbin::ctbin(const GObservations& obs) : | @@ -89,7 +89,6 @@ ctbin::ctbin(const GObservations& obs) : | ||
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | 91 | ||
| 92 | - | ||
| 93 | /***********************************************************************//** | 92 | /***********************************************************************//** |
| 94 | * @brief Command line constructor | 93 | * @brief Command line constructor |
| 95 | * | 94 | * |
| @@ -221,9 +220,9 @@ void ctbin::clear(void) | @@ -221,9 +220,9 @@ void ctbin::clear(void) | ||
| 221 | * @brief Run the event binning tool | 220 | * @brief Run the event binning tool |
| 222 | * | 221 | * |
| 223 | * Gets the user parameters and loops over all CTA observations in the | 222 | * Gets the user parameters and loops over all CTA observations in the |
| 224 | - * observation container to bin the events into a single counts cube. All | ||
| 225 | - * observations in the observation container that do not contain CTA event | ||
| 226 | - * lists will be skipped. | 223 | + * observation container to bin the events into either a single or a set of |
| 224 | + * counts cube. All observations in the observation container that do not | ||
| 225 | + * contain CTA event lists will be skipped. | ||
| 227 | ***************************************************************************/ | 226 | ***************************************************************************/ |
| 228 | void ctbin::run(void) | 227 | void ctbin::run(void) |
| 229 | { | 228 | { |
| @@ -281,9 +280,15 @@ void ctbin::run(void) | @@ -281,9 +280,15 @@ void ctbin::run(void) | ||
| 281 | 280 | ||
| 282 | // Initialise arrays | 281 | // Initialise arrays |
| 283 | if (nobs > 0) { | 282 | if (nobs > 0) { |
| 284 | - m_counts = std::vector<GSkyMap>(nobs); | ||
| 285 | - m_weights = std::vector<GSkyMap>(nobs); | ||
| 286 | - m_cubes = std::vector<GCTAEventCube>(nobs); | 283 | + |
| 284 | + // Determine number of cubes | ||
| 285 | + int ncubes = (m_stack) ? 1 : nobs; | ||
| 286 | + | ||
| 287 | + // Allocate cubes | ||
| 288 | + m_counts = std::vector<GSkyMap>(ncubes); | ||
| 289 | + m_weights = std::vector<GSkyMap>(ncubes); | ||
| 290 | + m_cubes = std::vector<GCTAEventCube>(ncubes); | ||
| 291 | + | ||
| 287 | } | 292 | } |
| 288 | else { | 293 | else { |
| 289 | m_counts.clear(); | 294 | m_counts.clear(); |
| @@ -316,46 +321,25 @@ void ctbin::run(void) | @@ -316,46 +321,25 @@ void ctbin::run(void) | ||
| 316 | // Get pointer to observation | 321 | // Get pointer to observation |
| 317 | GCTAObservation* obs = obs_list[i]; | 322 | GCTAObservation* obs = obs_list[i]; |
| 318 | 323 | ||
| 319 | - // Fill the cube | ||
| 320 | - GSkyMap counts = fill_cube(obs); | 324 | + // Determine counts cube slot |
| 325 | + int islot = (m_stack) ? 0 : i; | ||
| 326 | + | ||
| 327 | + // If slot is empty then allocate cubes | ||
| 328 | + #pragma omp critical(ctbin_run) | ||
| 329 | + if (m_counts[islot].is_empty()) { | ||
| 330 | + m_counts[islot] = create_cube(obs); | ||
| 331 | + m_weights[islot] = create_cube(obs); | ||
| 332 | + } | ||
| 333 | + | ||
| 334 | + // Fill counts cube | ||
| 335 | + fill_cube(obs, m_counts[islot]); | ||
| 321 | 336 | ||
| 322 | // Set the counts cube weights | 337 | // Set the counts cube weights |
| 323 | - GSkyMap weights = set_weights(obs); | 338 | + set_weights(obs, m_weights[islot]); |
| 324 | 339 | ||
| 325 | // Dispose events to free memory | 340 | // Dispose events to free memory |
| 326 | obs->dispose_events(); | 341 | obs->dispose_events(); |
| 327 | 342 | ||
| 328 | - // Post process cubes | ||
| 329 | - #pragma omp critical(ctbin_fill_cube) | ||
| 330 | - { | ||
| 331 | - // If stacking of cubes is requested then add up counts cube | ||
| 332 | - // and set weights in the first slot of the m_counts and | ||
| 333 | - // m_weights arrays | ||
| 334 | - if (m_stack) { | ||
| 335 | - if (m_counts[0].is_empty()) { | ||
| 336 | - m_counts[0] = counts; | ||
| 337 | - m_weights[0] = weights; | ||
| 338 | - } | ||
| 339 | - else { | ||
| 340 | - for (int iebin = 0; iebin < m_ebounds.size(); ++iebin) { | ||
| 341 | - for (int pixel = 0; pixel < counts.npix(); ++pixel) { | ||
| 342 | - m_counts[0](pixel, iebin) += counts(pixel, iebin); | ||
| 343 | - if (weights(pixel, iebin) == 1.0) { | ||
| 344 | - m_weights[0](pixel, iebin) = 1.0; | ||
| 345 | - } | ||
| 346 | - } | ||
| 347 | - } | ||
| 348 | - } | ||
| 349 | - } | ||
| 350 | - | ||
| 351 | - // ... otherwise store counts and weights | ||
| 352 | - else { | ||
| 353 | - m_counts[i] = counts; | ||
| 354 | - m_weights[i] = weights; | ||
| 355 | - } | ||
| 356 | - | ||
| 357 | - } // end: omp critical section | ||
| 358 | - | ||
| 359 | } // endfor: looped over observations | 343 | } // endfor: looped over observations |
| 360 | 344 | ||
| 361 | // Combine GTIs of all observations and compute total ontime and livetime | 345 | // Combine GTIs of all observations and compute total ontime and livetime |
| @@ -369,16 +353,16 @@ void ctbin::run(void) | @@ -369,16 +353,16 @@ void ctbin::run(void) | ||
| 369 | 353 | ||
| 370 | // If resulting GTI is not filled then copy over the reference from | 354 | // If resulting GTI is not filled then copy over the reference from |
| 371 | // the observation and use it for the resulting GTI | 355 | // the observation and use it for the resulting GTI |
| 372 | - if (m_gti.is_empty()) { | 356 | + if (m_gti.is_empty()) { |
| 373 | m_gti.reference(gti.reference()); | 357 | m_gti.reference(gti.reference()); |
| 374 | - } | 358 | + } |
| 375 | 359 | ||
| 376 | - // Append GTIs | ||
| 377 | - m_gti.extend(gti); | 360 | + // Append GTIs |
| 361 | + m_gti.extend(gti); | ||
| 378 | 362 | ||
| 379 | - // Update ontime and livetime | ||
| 380 | - m_ontime += obs->ontime(); | ||
| 381 | - m_livetime += obs->livetime(); | 363 | + // Update ontime and livetime |
| 364 | + m_ontime += obs->ontime(); | ||
| 365 | + m_livetime += obs->livetime(); | ||
| 382 | 366 | ||
| 383 | } // endfor: looped over all observations | 367 | } // endfor: looped over all observations |
| 384 | 368 | ||
| @@ -842,13 +826,14 @@ GSkyMap ctbin::create_cube(const GCTAObservation* obs) | @@ -842,13 +826,14 @@ GSkyMap ctbin::create_cube(const GCTAObservation* obs) | ||
| 842 | * @brief Fill events into counts cube | 826 | * @brief Fill events into counts cube |
| 843 | * | 827 | * |
| 844 | * @param[in] obs CTA observation. | 828 | * @param[in] obs CTA observation. |
| 829 | + * @param[in,out] counts Counts cube | ||
| 845 | * | 830 | * |
| 846 | * @exception GException::invalid_value | 831 | * @exception GException::invalid_value |
| 847 | * No event list or valid RoI found in observation. | 832 | * No event list or valid RoI found in observation. |
| 848 | * | 833 | * |
| 849 | * Fills the events from an event list into the counts cube. | 834 | * Fills the events from an event list into the counts cube. |
| 850 | ***************************************************************************/ | 835 | ***************************************************************************/ |
| 851 | -GSkyMap ctbin::fill_cube(const GCTAObservation* obs) | 836 | +void ctbin::fill_cube(const GCTAObservation* obs, GSkyMap& counts) |
| 852 | { | 837 | { |
| 853 | // Make sure that the observation holds a CTA event list. If this is | 838 | // Make sure that the observation holds a CTA event list. If this is |
| 854 | // not the case then throw an exception. | 839 | // not the case then throw an exception. |
| @@ -883,9 +868,6 @@ GSkyMap ctbin::fill_cube(const GCTAObservation* obs) | @@ -883,9 +868,6 @@ GSkyMap ctbin::fill_cube(const GCTAObservation* obs) | ||
| 883 | int num_outside_ebds = 0; | 868 | int num_outside_ebds = 0; |
| 884 | int num_in_map = 0; | 869 | int num_in_map = 0; |
| 885 | 870 | ||
| 886 | - // Create counts cube | ||
| 887 | - GSkyMap counts = create_cube(obs); | ||
| 888 | - | ||
| 889 | // Extract counts cube boundaries | 871 | // Extract counts cube boundaries |
| 890 | double pixel_x_max = counts.nx() - 0.5; | 872 | double pixel_x_max = counts.nx() - 0.5; |
| 891 | double pixel_y_max = counts.ny() - 0.5; | 873 | double pixel_y_max = counts.ny() - 0.5; |
| @@ -936,6 +918,7 @@ GSkyMap ctbin::fill_cube(const GCTAObservation* obs) | @@ -936,6 +918,7 @@ GSkyMap ctbin::fill_cube(const GCTAObservation* obs) | ||
| 936 | } | 918 | } |
| 937 | 919 | ||
| 938 | // Fill event in skymap | 920 | // Fill event in skymap |
| 921 | + #pragma omp atomic | ||
| 939 | counts(pixel, iebin) += 1.0; | 922 | counts(pixel, iebin) += 1.0; |
| 940 | 923 | ||
| 941 | // Increment number of maps | 924 | // Increment number of maps |
| @@ -956,7 +939,7 @@ GSkyMap ctbin::fill_cube(const GCTAObservation* obs) | @@ -956,7 +939,7 @@ GSkyMap ctbin::fill_cube(const GCTAObservation* obs) | ||
| 956 | } | 939 | } |
| 957 | 940 | ||
| 958 | // Return | 941 | // Return |
| 959 | - return counts; | 942 | + return; |
| 960 | } | 943 | } |
| 961 | 944 | ||
| 962 | 945 | ||
| @@ -964,6 +947,7 @@ GSkyMap ctbin::fill_cube(const GCTAObservation* obs) | @@ -964,6 +947,7 @@ GSkyMap ctbin::fill_cube(const GCTAObservation* obs) | ||
| 964 | * @brief Set counts cube weights for a given observation | 947 | * @brief Set counts cube weights for a given observation |
| 965 | * | 948 | * |
| 966 | * @param[in] obs CTA observation. | 949 | * @param[in] obs CTA observation. |
| 950 | + * @param[in,out] weights Counts cube weights. | ||
| 967 | * | 951 | * |
| 968 | * @exception GException::invalid_value | 952 | * @exception GException::invalid_value |
| 969 | * No event list or valid RoI found in observation. | 953 | * No event list or valid RoI found in observation. |
| @@ -971,7 +955,7 @@ GSkyMap ctbin::fill_cube(const GCTAObservation* obs) | @@ -971,7 +955,7 @@ GSkyMap ctbin::fill_cube(const GCTAObservation* obs) | ||
| 971 | * Sets the counts cube weights for all bins that are considered for the | 955 | * Sets the counts cube weights for all bins that are considered for the |
| 972 | * specific observation to unity. | 956 | * specific observation to unity. |
| 973 | ***************************************************************************/ | 957 | ***************************************************************************/ |
| 974 | -GSkyMap ctbin::set_weights(const GCTAObservation* obs) | 958 | +void ctbin::set_weights(const GCTAObservation* obs, GSkyMap& weights) |
| 975 | { | 959 | { |
| 976 | // Get the RoI | 960 | // Get the RoI |
| 977 | const GCTARoi& roi = obs->roi(); | 961 | const GCTARoi& roi = obs->roi(); |
| @@ -992,9 +976,6 @@ GSkyMap ctbin::set_weights(const GCTAObservation* obs) | @@ -992,9 +976,6 @@ GSkyMap ctbin::set_weights(const GCTAObservation* obs) | ||
| 992 | // Get counts cube usage flags | 976 | // Get counts cube usage flags |
| 993 | std::vector<bool> usage = cube_layer_usage(m_ebounds, obs->ebounds()); | 977 | std::vector<bool> usage = cube_layer_usage(m_ebounds, obs->ebounds()); |
| 994 | 978 | ||
| 995 | - // Create weights cube | ||
| 996 | - GSkyMap weights = create_cube(obs); | ||
| 997 | - | ||
| 998 | // Set sky direction cache availability flag | 979 | // Set sky direction cache availability flag |
| 999 | bool cache = (m_stack && m_dirs.size() == weights.npix()); | 980 | bool cache = (m_stack && m_dirs.size() == weights.npix()); |
| 1000 | 981 | ||
| @@ -1029,7 +1010,7 @@ GSkyMap ctbin::set_weights(const GCTAObservation* obs) | @@ -1029,7 +1010,7 @@ GSkyMap ctbin::set_weights(const GCTAObservation* obs) | ||
| 1029 | } // endfor: looped over pixels of counts cube | 1010 | } // endfor: looped over pixels of counts cube |
| 1030 | 1011 | ||
| 1031 | // Return | 1012 | // Return |
| 1032 | - return weights; | 1013 | + return; |
| 1033 | } | 1014 | } |
| 1034 | 1015 | ||
| 1035 | 1016 |
src/ctbin/ctbin.hpp
| 1 | /*************************************************************************** | 1 | /*************************************************************************** |
| 2 | * ctbin - Event binning tool * | 2 | * ctbin - Event binning tool * |
| 3 | * ----------------------------------------------------------------------- * | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2010-2018 by Juergen Knoedlseder * | 4 | + * copyright (C) 2010-2020 by Juergen Knoedlseder * |
| 5 | * ----------------------------------------------------------------------- * | 5 | * ----------------------------------------------------------------------- * |
| 6 | * * | 6 | * * |
| 7 | * This program is free software: you can redistribute it and/or modify * | 7 | * This program is free software: you can redistribute it and/or modify * |
| @@ -44,8 +44,8 @@ | @@ -44,8 +44,8 @@ | ||
| 44 | * FITS files, and on observation definition XML files. | 44 | * FITS files, and on observation definition XML files. |
| 45 | * | 45 | * |
| 46 | * If multiple event lists are specified in the observation container or the | 46 | * If multiple event lists are specified in the observation container or the |
| 47 | - * XML definition file, the class will merge these events into a single | ||
| 48 | - * counts cube. | 47 | + * XML definition file, the class will upon request stack these events into a |
| 48 | + * single counts cube. | ||
| 49 | * | 49 | * |
| 50 | * If the hidden parameter stack=no is used, one counts cube is generated for | 50 | * If the hidden parameter stack=no is used, one counts cube is generated for |
| 51 | * each individual observation. These cubes are saved to a path that can be | 51 | * each individual observation. These cubes are saved to a path that can be |
| @@ -94,8 +94,8 @@ protected: | @@ -94,8 +94,8 @@ protected: | ||
| 94 | void get_parameters(void); | 94 | void get_parameters(void); |
| 95 | void init_sky_dir_cache(void); | 95 | void init_sky_dir_cache(void); |
| 96 | GSkyMap create_cube(const GCTAObservation* obs); | 96 | GSkyMap create_cube(const GCTAObservation* obs); |
| 97 | - GSkyMap fill_cube(const GCTAObservation* obs); | ||
| 98 | - GSkyMap set_weights(const GCTAObservation* obs); | 97 | + void fill_cube(const GCTAObservation* obs, GSkyMap& counts); |
| 98 | + void set_weights(const GCTAObservation* obs, GSkyMap& weights); | ||
| 99 | void obs_cube_stacked(void); | 99 | void obs_cube_stacked(void); |
| 100 | 100 | ||
| 101 | // User parameters | 101 | // User parameters |