Commit 4c5082b89e72f9baaf2258218a0e3912861afd26
1 parent
f4de261c
Parallelize the simulation loop
Showing
3 changed files
with
125 additions
and
77 deletions
pyext/ctobssim.i
| @@ -52,8 +52,8 @@ public: | @@ -52,8 +52,8 @@ public: | ||
| 52 | GObservations& obs(void); | 52 | GObservations& obs(void); |
| 53 | void get_parameters(void); | 53 | void get_parameters(void); |
| 54 | void set_list(GCTAObservation* obs); | 54 | void set_list(GCTAObservation* obs); |
| 55 | - void simulate_source(GCTAObservation* obs, const GModels& models); | ||
| 56 | - void simulate_background(GCTAObservation* obs, const GModels& models); | 55 | + void simulate_source(GCTAObservation* obs, const GModels& models, GRan& ran, GLog* wrklog=NULL); |
| 56 | + void simulate_background(GCTAObservation* obs, const GModels& models, GRan& ran, GLog* wrklog=NULL); | ||
| 57 | }; | 57 | }; |
| 58 | 58 | ||
| 59 | 59 |
src/ctobssim/ctobssim.cpp
| @@ -264,38 +264,44 @@ void ctobssim::run(void) | @@ -264,38 +264,44 @@ void ctobssim::run(void) | ||
| 264 | // Initialise counters | 264 | // Initialise counters |
| 265 | int n_observations = 0; | 265 | int n_observations = 0; |
| 266 | 266 | ||
| 267 | - // Loop over all observation in the container | ||
| 268 | - for (int i = 0; i < m_obs.size(); ++i) { | ||
| 269 | - | ||
| 270 | - // Get CTA observation | ||
| 271 | - GCTAObservation* obs = dynamic_cast<GCTAObservation*>(&m_obs[i]); | ||
| 272 | - | ||
| 273 | - // Continue only if observation is a CTA observation | ||
| 274 | - if (obs != NULL) { | ||
| 275 | - | ||
| 276 | - // Write header for observation | ||
| 277 | - if (logTerse()) { | ||
| 278 | - if (obs->name().length() > 1) { | ||
| 279 | - log.header3("Observation "+obs->name()); | ||
| 280 | - } | ||
| 281 | - else { | ||
| 282 | - log.header3("Observation"); | ||
| 283 | - } | ||
| 284 | - } | ||
| 285 | - | ||
| 286 | - // Increment counter | ||
| 287 | - n_observations++; | ||
| 288 | - | ||
| 289 | - // Simulate source events | ||
| 290 | - simulate_source(obs, m_obs.models()); | ||
| 291 | - | ||
| 292 | - // Simulate source events | ||
| 293 | - simulate_background(obs, m_obs.models()); | ||
| 294 | - | ||
| 295 | - } // endif: CTA observation found | ||
| 296 | - | ||
| 297 | - } // endfor: looped over observations | 267 | + #pragma omp parallel |
| 268 | + { | ||
| 269 | + //each thread has his own variable; | ||
| 270 | + GLog wrklog(log); | ||
| 271 | + | ||
| 272 | + #pragma omp for | ||
| 273 | + // Loop over all observation in the container | ||
| 274 | + for (int i = 0; i < m_obs.size(); ++i) { | ||
| 275 | + | ||
| 276 | + // Get CTA observation | ||
| 277 | + GCTAObservation* obs = dynamic_cast<GCTAObservation*>(&m_obs[i]); | ||
| 278 | + | ||
| 279 | + // Continue only if observation is a CTA observation | ||
| 280 | + if (obs != NULL) { | ||
| 281 | + // Write header for observation | ||
| 282 | + if (logTerse()) { | ||
| 283 | + if (obs->name().length() > 1) { | ||
| 284 | + wrklog.header3("Observation "+obs->name()); | ||
| 285 | + } | ||
| 286 | + else { | ||
| 287 | + wrklog.header3("Observation"); | ||
| 288 | + } | ||
| 289 | + } | ||
| 290 | + // Increment counter | ||
| 291 | + n_observations++; | ||
| 292 | + | ||
| 293 | + // Simulate source events | ||
| 294 | + simulate_source(obs, m_obs.models(),m_rans[i],&wrklog); | ||
| 295 | + | ||
| 296 | + // Simulate source events | ||
| 297 | + simulate_background(obs, m_obs.models(),m_rans[i],&wrklog); | ||
| 298 | + | ||
| 299 | + } // endif: CTA observation found | ||
| 300 | + | ||
| 301 | + } // endfor: looped over observations | ||
| 298 | 302 | ||
| 303 | + } // end pragma omp parallel | ||
| 304 | + | ||
| 299 | // If more than a single observation has been handled then make sure that | 305 | // If more than a single observation has been handled then make sure that |
| 300 | // an XML file will be used for storage | 306 | // an XML file will be used for storage |
| 301 | if (n_observations > 1) { | 307 | if (n_observations > 1) { |
| @@ -419,7 +425,36 @@ void ctobssim::get_parameters(void) | @@ -419,7 +425,36 @@ void ctobssim::get_parameters(void) | ||
| 419 | } | 425 | } |
| 420 | 426 | ||
| 421 | // Initialise random number generator | 427 | // Initialise random number generator |
| 422 | - m_ran.seed(m_seed); | 428 | + //m_ran.seed(m_seed); |
| 429 | + | ||
| 430 | + GRan master(m_seed); | ||
| 431 | + std::vector<unsigned long long int> seeds; | ||
| 432 | + | ||
| 433 | + bool repeat = false; | ||
| 434 | + | ||
| 435 | + // Loop over all observation in the container | ||
| 436 | + for (int i = 0; i < m_obs.size(); ++i) { | ||
| 437 | + unsigned long long int new_seed; | ||
| 438 | + | ||
| 439 | + do { | ||
| 440 | + // Each seed will be unique | ||
| 441 | + new_seed = (unsigned long long int)(master.int64() * 1.0e2); | ||
| 442 | + repeat = false; | ||
| 443 | + for (int j = 0; j < seeds.size(); ++j) { | ||
| 444 | + if (new_seed == seeds[j]) { | ||
| 445 | + repeat = true; | ||
| 446 | + break; | ||
| 447 | + } | ||
| 448 | + } | ||
| 449 | + } while(repeat); | ||
| 450 | + | ||
| 451 | + //Add the seed to the vector | ||
| 452 | + seeds.push_back(new_seed); | ||
| 453 | + | ||
| 454 | + //Use the seed to create a GRan for the observation number i | ||
| 455 | + m_rans.push_back(GRan(new_seed)); | ||
| 456 | + } | ||
| 457 | + | ||
| 423 | 458 | ||
| 424 | // Return | 459 | // Return |
| 425 | return; | 460 | return; |
| @@ -524,11 +559,15 @@ void ctobssim::set_list(GCTAObservation* obs) | @@ -524,11 +559,15 @@ void ctobssim::set_list(GCTAObservation* obs) | ||
| 524 | * they can be scatter within the ROI and energy interval by the | 559 | * they can be scatter within the ROI and energy interval by the |
| 525 | * PSF and energy dispersion. | 560 | * PSF and energy dispersion. |
| 526 | ***************************************************************************/ | 561 | ***************************************************************************/ |
| 527 | -void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | 562 | +void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models, GRan& ran, GLog* wrklog) |
| 528 | { | 563 | { |
| 529 | // Continue only if observation pointer is valid | 564 | // Continue only if observation pointer is valid |
| 530 | if (obs != NULL) { | 565 | if (obs != NULL) { |
| 531 | - | 566 | + |
| 567 | + if(wrklog==NULL){ | ||
| 568 | + wrklog=&log; | ||
| 569 | + } | ||
| 570 | + | ||
| 532 | // Get pointer on CTA response. Throw an exception if the response | 571 | // Get pointer on CTA response. Throw an exception if the response |
| 533 | // is not defined. | 572 | // is not defined. |
| 534 | GCTAResponse* rsp = obs->response(); | 573 | GCTAResponse* rsp = obs->response(); |
| @@ -551,12 +590,12 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | @@ -551,12 +590,12 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | ||
| 551 | 590 | ||
| 552 | // Dump simulation cone information | 591 | // Dump simulation cone information |
| 553 | if (logNormal()) { | 592 | if (logNormal()) { |
| 554 | - log << parformat("Simulation area"); | ||
| 555 | - log << str(m_area) << " cm2" << std::endl; | ||
| 556 | - log << parformat("Simulation cone"); | ||
| 557 | - log << "RA=" << dir.ra_deg() << " deg"; | ||
| 558 | - log << ", Dec=" << dir.dec_deg() << " deg"; | ||
| 559 | - log << ", r=" << rad << " deg" << std::endl; | 593 | + *wrklog << parformat("Simulation area"); |
| 594 | + *wrklog << str(m_area) << " cm2" << std::endl; | ||
| 595 | + *wrklog << parformat("Simulation cone"); | ||
| 596 | + *wrklog << "RA=" << dir.ra_deg() << " deg"; | ||
| 597 | + *wrklog << ", Dec=" << dir.dec_deg() << " deg"; | ||
| 598 | + *wrklog << ", r=" << rad << " deg" << std::endl; | ||
| 560 | } | 599 | } |
| 561 | 600 | ||
| 562 | // Initialise indentation for logging | 601 | // Initialise indentation for logging |
| @@ -573,10 +612,10 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | @@ -573,10 +612,10 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | ||
| 573 | if (logNormal()) { | 612 | if (logNormal()) { |
| 574 | if (events->gti().size() > 1) { | 613 | if (events->gti().size() > 1) { |
| 575 | indent++; | 614 | indent++; |
| 576 | - log.indent(indent); | 615 | + wrklog->indent(indent); |
| 577 | } | 616 | } |
| 578 | - log << parformat("Time interval"); | ||
| 579 | - log << tmin << " - " << tmax << std::endl; | 617 | + *wrklog << parformat("Time interval"); |
| 618 | + *wrklog << tmin << " - " << tmax << std::endl; | ||
| 580 | } | 619 | } |
| 581 | 620 | ||
| 582 | // Loop over all energy boundaries | 621 | // Loop over all energy boundaries |
| @@ -590,10 +629,10 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | @@ -590,10 +629,10 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | ||
| 590 | if (logNormal()) { | 629 | if (logNormal()) { |
| 591 | if (events->ebounds().size() > 1) { | 630 | if (events->ebounds().size() > 1) { |
| 592 | indent++; | 631 | indent++; |
| 593 | - log.indent(indent); | 632 | + wrklog->indent(indent); |
| 594 | } | 633 | } |
| 595 | - log << parformat("Energy range"); | ||
| 596 | - log << emin << " - " << emax << std::endl; | 634 | + *wrklog << parformat("Energy range"); |
| 635 | + *wrklog << emin << " - " << emax << std::endl; | ||
| 597 | } | 636 | } |
| 598 | 637 | ||
| 599 | // Loop over all sky models | 638 | // Loop over all sky models |
| @@ -627,16 +666,17 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | @@ -627,16 +666,17 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | ||
| 627 | if (logExplicit()) { | 666 | if (logExplicit()) { |
| 628 | if (tmax - tmin > m_time_max) { | 667 | if (tmax - tmin > m_time_max) { |
| 629 | indent++; | 668 | indent++; |
| 630 | - log.indent(indent); | 669 | + wrklog->indent(indent); |
| 631 | } | 670 | } |
| 632 | - log << parformat("Time slice"); | ||
| 633 | - log << tstart << " - " << tstop << std::endl; | 671 | + *wrklog << parformat("Time slice"); |
| 672 | + *wrklog << tstart << " - " << tstop << std::endl; | ||
| 673 | + | ||
| 634 | } | 674 | } |
| 635 | 675 | ||
| 636 | // Get photons | 676 | // Get photons |
| 637 | GPhotons photons = model->mc(m_area, dir, rad, | 677 | GPhotons photons = model->mc(m_area, dir, rad, |
| 638 | emin, emax, | 678 | emin, emax, |
| 639 | - tstart, tstop, m_ran); | 679 | + tstart, tstop, ran); |
| 640 | 680 | ||
| 641 | // Simulate events from photons | 681 | // Simulate events from photons |
| 642 | for (int i = 0; i < photons.size(); ++i) { | 682 | for (int i = 0; i < photons.size(); ++i) { |
| @@ -649,7 +689,7 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | @@ -649,7 +689,7 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | ||
| 649 | GCTAEventAtom* event = rsp->mc(m_area, | 689 | GCTAEventAtom* event = rsp->mc(m_area, |
| 650 | photons[i], | 690 | photons[i], |
| 651 | *obs, | 691 | *obs, |
| 652 | - m_ran); | 692 | + ran); |
| 653 | if (event != NULL) { | 693 | if (event != NULL) { |
| 654 | events->append(*event); | 694 | events->append(*event); |
| 655 | delete event; | 695 | delete event; |
| @@ -665,7 +705,7 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | @@ -665,7 +705,7 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | ||
| 665 | if (logExplicit()) { | 705 | if (logExplicit()) { |
| 666 | if (tmax - tmin > m_time_max) { | 706 | if (tmax - tmin > m_time_max) { |
| 667 | indent--; | 707 | indent--; |
| 668 | - log.indent(indent); | 708 | + wrklog->indent(indent); |
| 669 | } | 709 | } |
| 670 | } | 710 | } |
| 671 | 711 | ||
| @@ -673,18 +713,19 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | @@ -673,18 +713,19 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | ||
| 673 | 713 | ||
| 674 | // Dump simulation results | 714 | // Dump simulation results |
| 675 | if (logNormal()) { | 715 | if (logNormal()) { |
| 676 | - log << parformat("MC source photons"); | ||
| 677 | - log << str(nphotons); | 716 | + *wrklog << parformat("MC source photons"); |
| 717 | + *wrklog << str(nphotons); | ||
| 678 | if (model->name().length() > 0) { | 718 | if (model->name().length() > 0) { |
| 679 | - log << " [" << model->name() << "]"; | 719 | + *wrklog << " [" << model->name() << "]"; |
| 680 | } | 720 | } |
| 681 | - log << std::endl; | ||
| 682 | - log << parformat("MC source events"); | ||
| 683 | - log << str(events->size()); | 721 | + *wrklog << std::endl; |
| 722 | + *wrklog << parformat("MC source events"); | ||
| 723 | + *wrklog << str(events->size()); | ||
| 684 | if (model->name().length() > 0) { | 724 | if (model->name().length() > 0) { |
| 685 | - log << " [" << model->name() << "]"; | 725 | + *wrklog << " [" << model->name() << "]"; |
| 686 | } | 726 | } |
| 687 | - log << std::endl; | 727 | + *wrklog << std::endl; |
| 728 | + | ||
| 688 | } | 729 | } |
| 689 | 730 | ||
| 690 | } // endif: model was a sky model | 731 | } // endif: model was a sky model |
| @@ -693,17 +734,18 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | @@ -693,17 +734,18 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | ||
| 693 | 734 | ||
| 694 | // Dump simulation results | 735 | // Dump simulation results |
| 695 | if (logNormal()) { | 736 | if (logNormal()) { |
| 696 | - log << parformat("MC source events"); | ||
| 697 | - log << str(events->size()); | ||
| 698 | - log << " (all source models)"; | ||
| 699 | - log << std::endl; | 737 | + *wrklog << parformat("MC source events"); |
| 738 | + *wrklog << str(events->size()); | ||
| 739 | + *wrklog << " (all source models)"; | ||
| 740 | + *wrklog << std::endl; | ||
| 700 | } | 741 | } |
| 701 | 742 | ||
| 702 | // Reset indentation | 743 | // Reset indentation |
| 703 | if (logNormal()) { | 744 | if (logNormal()) { |
| 704 | if (events->ebounds().size() > 1) { | 745 | if (events->ebounds().size() > 1) { |
| 705 | indent--; | 746 | indent--; |
| 706 | - log.indent(indent); | 747 | + wrklog->indent(indent); |
| 748 | + | ||
| 707 | } | 749 | } |
| 708 | } | 750 | } |
| 709 | 751 | ||
| @@ -713,14 +755,15 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | @@ -713,14 +755,15 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | ||
| 713 | if (logNormal()) { | 755 | if (logNormal()) { |
| 714 | if (events->gti().size() > 1) { | 756 | if (events->gti().size() > 1) { |
| 715 | indent--; | 757 | indent--; |
| 716 | - log.indent(indent); | 758 | + wrklog->indent(indent); |
| 759 | + | ||
| 717 | } | 760 | } |
| 718 | } | 761 | } |
| 719 | 762 | ||
| 720 | } // endfor: looped over all time intervals | 763 | } // endfor: looped over all time intervals |
| 721 | 764 | ||
| 722 | // Reset indentation | 765 | // Reset indentation |
| 723 | - log.indent(0); | 766 | + wrklog->indent(0); |
| 724 | 767 | ||
| 725 | } // endif: observation pointer was valid | 768 | } // endif: observation pointer was valid |
| 726 | 769 | ||
| @@ -740,11 +783,15 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | @@ -740,11 +783,15 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) | ||
| 740 | * | 783 | * |
| 741 | * This method does nothing if the observation pointer is NULL. | 784 | * This method does nothing if the observation pointer is NULL. |
| 742 | ***************************************************************************/ | 785 | ***************************************************************************/ |
| 743 | -void ctobssim::simulate_background(GCTAObservation* obs, const GModels& models) | 786 | +void ctobssim::simulate_background(GCTAObservation* obs, const GModels& models, GRan& ran, GLog* wrklog) |
| 744 | { | 787 | { |
| 745 | // Continue only if observation pointer is valid | 788 | // Continue only if observation pointer is valid |
| 746 | if (obs != NULL) { | 789 | if (obs != NULL) { |
| 747 | 790 | ||
| 791 | + if(wrklog==NULL){ | ||
| 792 | + wrklog=&log; | ||
| 793 | + } | ||
| 794 | + | ||
| 748 | // Make sure that the observation holds a CTA event list. If this | 795 | // Make sure that the observation holds a CTA event list. If this |
| 749 | // is not the case then allocate and attach a CTA event list now. | 796 | // is not the case then allocate and attach a CTA event list now. |
| 750 | if (dynamic_cast<const GCTAEventList*>(obs->events()) == NULL) { | 797 | if (dynamic_cast<const GCTAEventList*>(obs->events()) == NULL) { |
| @@ -766,7 +813,7 @@ void ctobssim::simulate_background(GCTAObservation* obs, const GModels& models) | @@ -766,7 +813,7 @@ void ctobssim::simulate_background(GCTAObservation* obs, const GModels& models) | ||
| 766 | 813 | ||
| 767 | // Get simulated event list. Note that this method includes | 814 | // Get simulated event list. Note that this method includes |
| 768 | // the deadtime correction. | 815 | // the deadtime correction. |
| 769 | - GCTAEventList* list = model->mc(*obs, m_ran); | 816 | + GCTAEventList* list = model->mc(*obs, ran); |
| 770 | 817 | ||
| 771 | // Reserves space for events | 818 | // Reserves space for events |
| 772 | events->reserve(list->size()+events->size()); | 819 | events->reserve(list->size()+events->size()); |
| @@ -784,8 +831,8 @@ void ctobssim::simulate_background(GCTAObservation* obs, const GModels& models) | @@ -784,8 +831,8 @@ void ctobssim::simulate_background(GCTAObservation* obs, const GModels& models) | ||
| 784 | 831 | ||
| 785 | // Dump simulation results | 832 | // Dump simulation results |
| 786 | if (logNormal()) { | 833 | if (logNormal()) { |
| 787 | - log << parformat("MC background events"); | ||
| 788 | - log << str(list->size()) << std::endl; | 834 | + *wrklog << parformat("MC background events"); |
| 835 | + *wrklog << str(list->size()) << std::endl; | ||
| 789 | } | 836 | } |
| 790 | 837 | ||
| 791 | // Free event list | 838 | // Free event list |
| @@ -875,7 +922,7 @@ void ctobssim::copy_members(const ctobssim& app) | @@ -875,7 +922,7 @@ void ctobssim::copy_members(const ctobssim& app) | ||
| 875 | // Copy protected members | 922 | // Copy protected members |
| 876 | m_area = app.m_area; | 923 | m_area = app.m_area; |
| 877 | m_time_max = app.m_time_max; | 924 | m_time_max = app.m_time_max; |
| 878 | - m_ran = app.m_ran; | 925 | + m_rans = app.m_rans; |
| 879 | m_obs = app.m_obs; | 926 | m_obs = app.m_obs; |
| 880 | m_use_xml = app.m_use_xml; | 927 | m_use_xml = app.m_use_xml; |
| 881 | m_read_ahead = app.m_read_ahead; | 928 | m_read_ahead = app.m_read_ahead; |
src/ctobssim/ctobssim.hpp
| @@ -67,8 +67,8 @@ public: | @@ -67,8 +67,8 @@ public: | ||
| 67 | GObservations& obs(void) { return m_obs; } | 67 | GObservations& obs(void) { return m_obs; } |
| 68 | void get_parameters(void); | 68 | void get_parameters(void); |
| 69 | void set_list(GCTAObservation* obs); | 69 | void set_list(GCTAObservation* obs); |
| 70 | - void simulate_source(GCTAObservation* obs, const GModels& models); | ||
| 71 | - void simulate_background(GCTAObservation* obs, const GModels& models); | 70 | + void simulate_source(GCTAObservation* obs, const GModels& models,GRan& ran, GLog* wrklog=NULL); |
| 71 | + void simulate_background(GCTAObservation* obs, const GModels& models,GRan& ran, GLog* wrklog=NULL); | ||
| 72 | 72 | ||
| 73 | protected: | 73 | protected: |
| 74 | // Protected methods | 74 | // Protected methods |
| @@ -97,7 +97,8 @@ protected: | @@ -97,7 +97,8 @@ protected: | ||
| 97 | // Protected members | 97 | // Protected members |
| 98 | double m_area; //!< Surface area for simulation (cm2) | 98 | double m_area; //!< Surface area for simulation (cm2) |
| 99 | GTime m_time_max; //!< Maximum length of time slice (sec) | 99 | GTime m_time_max; //!< Maximum length of time slice (sec) |
| 100 | - GRan m_ran; //!< Random number generator | 100 | + //GRan m_ran; //!< Random number generator |
| 101 | + std::vector<GRan> m_rans; //!< Random number generators | ||
| 101 | GObservations m_obs; //!< Observation container | 102 | GObservations m_obs; //!< Observation container |
| 102 | bool m_use_xml; //!< Use XML file instead of FITS file | 103 | bool m_use_xml; //!< Use XML file instead of FITS file |
| 103 | bool m_read_ahead; //!< Read ahead parameters | 104 | bool m_read_ahead; //!< Read ahead parameters |