|
86 | 86 | #endif |
87 | 87 |
|
88 | 88 | #include <tbb/concurrent_unordered_map.h> |
| 89 | +#include <tbb/parallel_for_each.h> |
| 90 | +#include <tbb/task_group.h> |
89 | 91 |
|
90 | 92 | namespace o2 |
91 | 93 | { |
@@ -787,68 +789,56 @@ class O2HitMerger : public fair::mq::Device |
787 | 789 | eventheader->putInfo("prims_eta_0.8_pi", eta0Point8CounterPi); |
788 | 790 | eventheader->putInfo("prims_total", prims); |
789 | 791 | }; |
790 | | - reorderAndMergeMCTracks(flusheventID, mOutTree, nprimaries, subevOrdered, mcheaderhook, eventheader); |
791 | | - |
792 | | - if (mOutTree) { |
793 | | - // adjusting and merging track references |
794 | | - remapTrackIdsAndMerge<std::vector<o2::TrackReference>>("TrackRefs", flusheventID, *mOutTree, trackoffsets, nprimaries, subevOrdered, mTrackRefBuffer); |
795 | | - |
796 | | - // write MC event headers |
797 | | - { |
798 | | - auto headerbr = o2::base::getOrMakeBranch(*mOutTree, "MCEventHeader.", &eventheader); |
799 | | - headerbr->SetAddress(&eventheader); |
800 | | - headerbr->Fill(); |
801 | | - headerbr->ResetAddress(); |
802 | | - } |
| 792 | + // the kinematics and each detector go to separate files, so we merge and flush them concurrently |
| 793 | + tbb::task_group tasks; |
| 794 | + tasks.run([&]() { |
| 795 | + reorderAndMergeMCTracks(flusheventID, mOutTree, nprimaries, subevOrdered, mcheaderhook, eventheader); |
| 796 | + |
| 797 | + if (mOutTree) { |
| 798 | + // adjusting and merging track references |
| 799 | + remapTrackIdsAndMerge<std::vector<o2::TrackReference>>("TrackRefs", flusheventID, *mOutTree, trackoffsets, nprimaries, subevOrdered, mTrackRefBuffer); |
| 800 | + |
| 801 | + // write MC event headers |
| 802 | + for (auto tree : {mOutTree, mMCHeaderTree}) { |
| 803 | + auto headerbr = o2::base::getOrMakeBranch(*tree, "MCEventHeader.", &eventheader); |
| 804 | + headerbr->SetAddress(&eventheader); |
| 805 | + headerbr->Fill(); |
| 806 | + headerbr->ResetAddress(); |
| 807 | + } |
803 | 808 |
|
804 | | - { |
805 | | - auto headerbr = o2::base::getOrMakeBranch(*mMCHeaderTree, "MCEventHeader.", &eventheader); |
806 | | - headerbr->SetAddress(&eventheader); |
807 | | - headerbr->Fill(); |
808 | | - headerbr->ResetAddress(); |
| 809 | + // increase the entry count in the trees |
| 810 | + mOutTree->SetEntries(mOutTree->GetEntries() + 1); |
| 811 | + mMCHeaderTree->SetEntries(mMCHeaderTree->GetEntries() + 1); |
809 | 812 | } |
810 | | - } |
| 813 | + }); |
811 | 814 |
|
812 | 815 | // c) do the merge procedure for all hits ... delegate this to detector specific functions |
813 | 816 | // since they know about types; number of branches; etc. |
814 | 817 | // this will also fix the trackIDs inside the hits |
815 | 818 | for (int id = 0; id < mDetectorInstances.size(); ++id) { |
816 | 819 | auto& det = mDetectorInstances[id]; |
817 | | - if (det) { |
818 | | - auto hittree = mDetectorToTTreeMap[id]; |
819 | | - if (hittree) { |
| 820 | + auto hittree = det ? mDetectorToTTreeMap[id] : nullptr; |
| 821 | + if (hittree) { |
| 822 | + tasks.run([&, det = det.get(), hittree]() { |
820 | 823 | det->mergeHitEntriesAndFlush(flusheventID, *hittree, trackoffsets, nprimaries, subevOrdered); |
821 | 824 | hittree->SetEntries(hittree->GetEntries() + 1); |
822 | | - LOG(info) << "flushing tree to file " << hittree->GetDirectory()->GetFile()->GetName(); |
823 | | - } |
| 825 | + }); |
824 | 826 | } |
825 | 827 | } |
826 | | - |
827 | | - // increase the entry count in the tree |
828 | | - if (mOutTree) { |
829 | | - mOutTree->SetEntries(mOutTree->GetEntries() + 1); |
830 | | - LOG(info) << "outtree has file " << mOutTree->GetDirectory()->GetFile()->GetName(); |
831 | | - } |
832 | | - if (mMCHeaderTree) { |
833 | | - mMCHeaderTree->SetEntries(mMCHeaderTree->GetEntries() + 1); |
834 | | - LOG(info) << "mc header outtree has file " << mMCHeaderTree->GetDirectory()->GetFile()->GetName(); |
835 | | - } |
| 828 | + tasks.wait(); |
836 | 829 |
|
837 | 830 | cleanEvent(flusheventID); |
838 | 831 | LOG(info) << "Merge/flush for event " << flusheventID << " took " << timer.RealTime(); |
839 | 832 | } |
840 | 833 | if (mWriteToDisc && mOutFile) { |
841 | 834 | LOG(info) << "Writing TTrees"; |
842 | | - mOutFile->Write("", TObject::kOverwrite); |
| 835 | + std::vector<TFile*> files{mOutFile, mMCHeaderOnlyOutFile}; |
843 | 836 | for (int id = 0; id < mDetectorInstances.size(); ++id) { |
844 | | - auto& det = mDetectorInstances[id]; |
845 | | - if (det && mDetectorOutFiles[id]) { |
846 | | - mDetectorOutFiles[id]->Write("", TObject::kOverwrite); |
| 837 | + if (mDetectorInstances[id] && mDetectorOutFiles[id]) { |
| 838 | + files.push_back(mDetectorOutFiles[id]); |
847 | 839 | } |
848 | 840 | } |
849 | | - if (mMCHeaderOnlyOutFile) { |
850 | | - mMCHeaderOnlyOutFile->Write("", TObject::kOverwrite); |
851 | | - } |
| 841 | + tbb::parallel_for_each(files, [](TFile* file) { file->Write("", TObject::kOverwrite); }); |
852 | 842 | } |
853 | 843 | return true; |
854 | 844 | } |
|
0 commit comments