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 | 52 | GObservations& obs(void); |
| 53 | 53 | void get_parameters(void); |
| 54 | 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 | 264 | // Initialise counters |
| 265 | 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 | 305 | // If more than a single observation has been handled then make sure that |
| 300 | 306 | // an XML file will be used for storage |
| 301 | 307 | if (n_observations > 1) { |
| ... | ... | @@ -419,7 +425,36 @@ void ctobssim::get_parameters(void) |
| 419 | 425 | } |
| 420 | 426 | |
| 421 | 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 | 459 | // Return |
| 425 | 460 | return; |
| ... | ... | @@ -524,11 +559,15 @@ void ctobssim::set_list(GCTAObservation* obs) |
| 524 | 559 | * they can be scatter within the ROI and energy interval by the |
| 525 | 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 | 564 | // Continue only if observation pointer is valid |
| 530 | 565 | if (obs != NULL) { |
| 531 | - | |
| 566 | + | |
| 567 | + if(wrklog==NULL){ | |
| 568 | + wrklog=&log; | |
| 569 | + } | |
| 570 | + | |
| 532 | 571 | // Get pointer on CTA response. Throw an exception if the response |
| 533 | 572 | // is not defined. |
| 534 | 573 | GCTAResponse* rsp = obs->response(); |
| ... | ... | @@ -551,12 +590,12 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) |
| 551 | 590 | |
| 552 | 591 | // Dump simulation cone information |
| 553 | 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 | 601 | // Initialise indentation for logging |
| ... | ... | @@ -573,10 +612,10 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) |
| 573 | 612 | if (logNormal()) { |
| 574 | 613 | if (events->gti().size() > 1) { |
| 575 | 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 | 621 | // Loop over all energy boundaries |
| ... | ... | @@ -590,10 +629,10 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) |
| 590 | 629 | if (logNormal()) { |
| 591 | 630 | if (events->ebounds().size() > 1) { |
| 592 | 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 | 638 | // Loop over all sky models |
| ... | ... | @@ -627,16 +666,17 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) |
| 627 | 666 | if (logExplicit()) { |
| 628 | 667 | if (tmax - tmin > m_time_max) { |
| 629 | 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 | 676 | // Get photons |
| 637 | 677 | GPhotons photons = model->mc(m_area, dir, rad, |
| 638 | 678 | emin, emax, |
| 639 | - tstart, tstop, m_ran); | |
| 679 | + tstart, tstop, ran); | |
| 640 | 680 | |
| 641 | 681 | // Simulate events from photons |
| 642 | 682 | for (int i = 0; i < photons.size(); ++i) { |
| ... | ... | @@ -649,7 +689,7 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) |
| 649 | 689 | GCTAEventAtom* event = rsp->mc(m_area, |
| 650 | 690 | photons[i], |
| 651 | 691 | *obs, |
| 652 | - m_ran); | |
| 692 | + ran); | |
| 653 | 693 | if (event != NULL) { |
| 654 | 694 | events->append(*event); |
| 655 | 695 | delete event; |
| ... | ... | @@ -665,7 +705,7 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) |
| 665 | 705 | if (logExplicit()) { |
| 666 | 706 | if (tmax - tmin > m_time_max) { |
| 667 | 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 | 713 | |
| 674 | 714 | // Dump simulation results |
| 675 | 715 | if (logNormal()) { |
| 676 | - log << parformat("MC source photons"); | |
| 677 | - log << str(nphotons); | |
| 716 | + *wrklog << parformat("MC source photons"); | |
| 717 | + *wrklog << str(nphotons); | |
| 678 | 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 | 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 | 731 | } // endif: model was a sky model |
| ... | ... | @@ -693,17 +734,18 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) |
| 693 | 734 | |
| 694 | 735 | // Dump simulation results |
| 695 | 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 | 743 | // Reset indentation |
| 703 | 744 | if (logNormal()) { |
| 704 | 745 | if (events->ebounds().size() > 1) { |
| 705 | 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 | 755 | if (logNormal()) { |
| 714 | 756 | if (events->gti().size() > 1) { |
| 715 | 757 | indent--; |
| 716 | - log.indent(indent); | |
| 758 | + wrklog->indent(indent); | |
| 759 | + | |
| 717 | 760 | } |
| 718 | 761 | } |
| 719 | 762 | |
| 720 | 763 | } // endfor: looped over all time intervals |
| 721 | 764 | |
| 722 | 765 | // Reset indentation |
| 723 | - log.indent(0); | |
| 766 | + wrklog->indent(0); | |
| 724 | 767 | |
| 725 | 768 | } // endif: observation pointer was valid |
| 726 | 769 | |
| ... | ... | @@ -740,11 +783,15 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models) |
| 740 | 783 | * |
| 741 | 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 | 788 | // Continue only if observation pointer is valid |
| 746 | 789 | if (obs != NULL) { |
| 747 | 790 | |
| 791 | + if(wrklog==NULL){ | |
| 792 | + wrklog=&log; | |
| 793 | + } | |
| 794 | + | |
| 748 | 795 | // Make sure that the observation holds a CTA event list. If this |
| 749 | 796 | // is not the case then allocate and attach a CTA event list now. |
| 750 | 797 | if (dynamic_cast<const GCTAEventList*>(obs->events()) == NULL) { |
| ... | ... | @@ -766,7 +813,7 @@ void ctobssim::simulate_background(GCTAObservation* obs, const GModels& models) |
| 766 | 813 | |
| 767 | 814 | // Get simulated event list. Note that this method includes |
| 768 | 815 | // the deadtime correction. |
| 769 | - GCTAEventList* list = model->mc(*obs, m_ran); | |
| 816 | + GCTAEventList* list = model->mc(*obs, ran); | |
| 770 | 817 | |
| 771 | 818 | // Reserves space for events |
| 772 | 819 | events->reserve(list->size()+events->size()); |
| ... | ... | @@ -784,8 +831,8 @@ void ctobssim::simulate_background(GCTAObservation* obs, const GModels& models) |
| 784 | 831 | |
| 785 | 832 | // Dump simulation results |
| 786 | 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 | 838 | // Free event list |
| ... | ... | @@ -875,7 +922,7 @@ void ctobssim::copy_members(const ctobssim& app) |
| 875 | 922 | // Copy protected members |
| 876 | 923 | m_area = app.m_area; |
| 877 | 924 | m_time_max = app.m_time_max; |
| 878 | - m_ran = app.m_ran; | |
| 925 | + m_rans = app.m_rans; | |
| 879 | 926 | m_obs = app.m_obs; |
| 880 | 927 | m_use_xml = app.m_use_xml; |
| 881 | 928 | m_read_ahead = app.m_read_ahead; | ... | ... |
src/ctobssim/ctobssim.hpp
| ... | ... | @@ -67,8 +67,8 @@ public: |
| 67 | 67 | GObservations& obs(void) { return m_obs; } |
| 68 | 68 | void get_parameters(void); |
| 69 | 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 | 73 | protected: |
| 74 | 74 | // Protected methods |
| ... | ... | @@ -97,7 +97,8 @@ protected: |
| 97 | 97 | // Protected members |
| 98 | 98 | double m_area; //!< Surface area for simulation (cm2) |
| 99 | 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 | 102 | GObservations m_obs; //!< Observation container |
| 102 | 103 | bool m_use_xml; //!< Use XML file instead of FITS file |
| 103 | 104 | bool m_read_ahead; //!< Read ahead parameters | ... | ... |