From 8577d35a2f615ba2e5777882dec64de4206450ca Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Fri, 2 Mar 2018 19:11:22 +0300 Subject: [PATCH 01/24] ... --- .gitignore | 2 + Dockerfile | 58 ++++++++++ data/background_spectra/README | 2 - data/background_spectra/e+.root | Bin 5321 -> 5479 bytes data/background_spectra/e-.root | Bin 5319 -> 5484 bytes data/background_spectra/gamma.root | Bin 5202 -> 5511 bytes data/background_spectra/mu+.root | Bin 5318 -> 5498 bytes data/background_spectra/mu-.root | Bin 5317 -> 5498 bytes data/background_spectra/neutron.root | Bin 5209 -> 0 bytes data/background_spectra/proton.root | Bin 5167 -> 5511 bytes data/diff_spectra/README | 2 + data/diff_spectra/e+.dat | 81 ++++++++++++++ data/diff_spectra/e-.dat | 81 ++++++++++++++ data/diff_spectra/gamma.dat | 81 ++++++++++++++ data/diff_spectra/mu+.dat | 81 ++++++++++++++ data/diff_spectra/mu-.dat | 81 ++++++++++++++ data/diff_spectra/neutron.dat | 80 ++++++++++++++ data/diff_spectra/proton.dat | 80 ++++++++++++++ run.py | 14 +++ run.sh | 5 + scripts/configs.py | 159 ++++++++++++++++++--------- 21 files changed, 756 insertions(+), 51 deletions(-) create mode 100644 Dockerfile delete mode 100644 data/background_spectra/README delete mode 100644 data/background_spectra/neutron.root create mode 100644 data/diff_spectra/README create mode 100644 data/diff_spectra/e+.dat create mode 100644 data/diff_spectra/e-.dat create mode 100644 data/diff_spectra/gamma.dat create mode 100644 data/diff_spectra/mu+.dat create mode 100644 data/diff_spectra/mu-.dat create mode 100644 data/diff_spectra/neutron.dat create mode 100644 data/diff_spectra/proton.dat create mode 100644 run.py create mode 100644 run.sh diff --git a/.gitignore b/.gitignore index c23f93b..cd5e796 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ bin/ configs/ events/ + +data/background_spectra/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a034253 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,58 @@ +FROM ubuntu:16.04 + +ENV TERM XTerm + +RUN apt-get update +RUN apt-get install -y wget + + +### ROOT +WORKDIR /usr/opt/ + +RUN wget https://root.cern.ch/download/root_v6.12.06.Linux-ubuntu16-x86_64-gcc5.4.tar.gz +RUN tar xvfz root_v6.12.06.Linux-ubuntu16-x86_64-gcc5.4.tar.gz +WORKDIR /usr/opt/root + +RUN apt-get install -y apt-utils cmake +RUN apt-get install -y libtbb2 g++ gcc +RUN apt-get install -y python +RUN apt-get install -y make +RUN apt-get install -y python-dev + +### GEANT +WORKDIR /usr/opt + +RUN wget http://geant4.web.cern.ch/geant4/support/source/geant4.10.01.p03.tar.gz +RUN tar xvfz geant4.10.01.p03.tar.gz + +WORKDIR /usr/opt/geant_build + +RUN cmake -DCMAKE_INSTALL_PREFIX=/usr/opt/geant -DGEANT4_INSTALL_DATA=ON -DBUILD_SHARED_LIBS=ON /usr/opt/geant4.10.01.p03/ +RUN make -j8 +RUN make install +RUN rm -rf /usr/opt/geant_build + +### CRAYFIS-SIM + +COPY data/ /usr/app/data +COPY include/ /usr/app/include +COPY src/ /usr/app/src +COPY scripts/ /usr/app/scripts +COPY GNUmakefile /usr/app/ +COPY TestEm1.cc /usr/app/ + +WORKDIR /usr/app/ + +RUN bash -c "export G4INSTALL=/usr/opt/geant/ && source /usr/opt/root/bin/thisroot.sh && source /usr/opt/geant/share/Geant4-10.1.3/geant4make/geant4make.sh && export G4G4WORKDIR=/usr/geant_workdir && make -j9" + +RUN apt-get install -y python-pip + +RUN pip install numpy + +WORKDIR /usr/app/ +RUN bash -c "source /usr/opt/root/bin/thisroot.sh && python scripts/configs.py 100 -j10 -o /output" + +COPY run.sh /usr/app/ +COPY run.py /usr/app/ + +CMD sh run.sh diff --git a/data/background_spectra/README b/data/background_spectra/README deleted file mode 100644 index 222a3df..0000000 --- a/data/background_spectra/README +++ /dev/null @@ -1,2 +0,0 @@ -Each file contains histograms for background cosmic radiation at sea level. -Energy is given in MeV, flux is in 1 / s / cm^-2. diff --git a/data/background_spectra/e+.root b/data/background_spectra/e+.root index 73609168a4b2cb3c887c1ee03bd78a8ff531f901..bef22aecd97016c627aa7a8046d7456dc8f83301 100644 GIT binary patch literal 5479 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 ACIA2c literal 5321 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 diff --git a/data/background_spectra/e-.root b/data/background_spectra/e-.root index 13087e5af717d910a4e8ae087d7436e7a4944900..74381ac132fa16b9c639cc799af4e281e865559d 100644 GIT binary patch literal 5484 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 literal 5319 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 bM}hEvDEtc?@BSJ74;1bQP!0QurUU*9_=3m? diff --git a/data/background_spectra/gamma.root b/data/background_spectra/gamma.root index 11a4dc88a7113c044b45f854704e9f906edbdf4d..117636a2cbff54b259d757051d887a465e8e6a0e 100644 GIT binary patch literal 5511 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 R5&tpKH4meYm&AL(e*s4gA4dQH literal 5318 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 XApY5nH>ZaG4~QEGG<|;JZvp=SK~BMw diff --git a/data/background_spectra/mu-.root b/data/background_spectra/mu-.root index dacfda71f1abe0041ddcefb914ccb02e43dbc219..fb91d50dcdefe4613231908156d7f394c9b4023d 100644 GIT binary patch literal 5498 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 PnCOm&+Rt0$J>b6pEMph} literal 5317 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

6uFx$IlY-Y98HU~}`7=sN%%|2R<++~5OVpvMb zaq7!KGF%7B2+>yKdu#ssUj!%p&#?cC;O@h(e}?`45y9OL-aG#PYc_U21^P#V;J-=y VOB?V18vZ{d?kQ09`b)h5{0D)0ybS;V diff --git a/data/background_spectra/neutron.root b/data/background_spectra/neutron.root deleted file mode 100644 index 13fea72ea2399cfe9a63ad539bfe351f3f67f938..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5209 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 diff --git a/data/background_spectra/proton.root b/data/background_spectra/proton.root index 11a01242a953bb94a30181ece33c5adc5ad83f65..eb90c55f0950c9d7a5b8e3d78dfb866efdb46aa8 100644 GIT binary patch literal 5511 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 PN#&LZ4cJfO4dA~3*L!Xb diff --git a/data/diff_spectra/README b/data/diff_spectra/README new file mode 100644 index 0000000..8c4f7f6 --- /dev/null +++ b/data/diff_spectra/README @@ -0,0 +1,2 @@ +Source: https://github.com/swaneyjr/AirplaneCosmicSpectrum +This is DIFFERENTIAL spectra at sea level. diff --git a/data/diff_spectra/e+.dat b/data/diff_spectra/e+.dat new file mode 100644 index 0000000..d1966f6 --- /dev/null +++ b/data/diff_spectra/e+.dat @@ -0,0 +1,81 @@ +0.011294 6.912754113714E-06 +0.014219 8.21569988483745E-06 +0.017901 9.75536350688826E-06 +0.022536 1.15698910449686E-05 +0.028371 1.37008769139771E-05 +0.035717 1.61919015498089E-05 +0.044965 1.90857935076182E-05 +0.056607 2.24204923660206E-05 +0.071264 2.62230479522847E-05 +0.089717 3.04998153580735E-05 +0.11294 3.52230304776175E-05 +0.14219 4.03244964991915E-05 +0.17901 4.56701327863593E-05 +0.22536 5.10618981723173E-05 +0.28371 5.62379659303892E-05 +0.35717 6.08918423374971E-05 +0.44965 6.47096595742407E-05 +0.56608 6.74204824678977E-05 +0.71264 6.88439516065054E-05 +0.89717 6.8922031920449E-05 +1.1294 6.77214152675347E-05 +1.4219 6.54077624829588E-05 +1.7901 6.22089785794004E-05 +2.2536 5.83699105710532E-05 +2.8371 5.41190466647287E-05 +3.5717 4.96485573764971E-05 +4.4965 4.51069203985617E-05 +5.6607 4.0600046230926E-05 +7.1265 3.61973079903103E-05 +8.9717 3.19431779815502E-05 +11.295 2.78641433794673E-05 +14.219 2.39824989441335E-05 +17.901 2.03182078019703E-05 +22.536 1.69015092585623E-05 +28.371 1.3769141542965E-05 +35.717 1.09620569797416E-05 +44.965 8.51689202252719E-06 +56.607 6.45545551391666E-06 +71.265 4.77695221341802E-06 +89.716 3.45751280111317E-06 +112.94 2.45396751323077E-06 +142.19 1.71249579881554E-06 +179.01 1.17869822915547E-06 +225.36 8.02354861555871E-07 +283.71 5.41433332065681E-07 +357.17 3.62906731850952E-07 +449.65 2.42002279868683E-07 +566.08 1.60753006108832E-07 +712.65 1.06476055954714E-07 +897.16 7.0375311497041E-08 +1129.4 4.64436475294839E-08 +1421.9 3.06086385371354E-08 +1790.1 2.01562560943039E-08 +2253.6 1.32652567241597E-08 +2837.1 8.72613961725299E-09 +3571.7 5.73819923819996E-09 +4496.5 3.77243353674064E-09 +5660.8 2.47959846906465E-09 +7126.5 1.62963905260313E-09 +8971.7 1.07092446820664E-09 +11294 7.03787203225651E-10 +14219 4.62394936118268E-10 +17901 3.03802828656652E-10 +22536 1.99606272630061E-10 +28371 1.31144706355964E-10 +35717 8.61620850615325E-11 +44965 5.66080420262388E-11 +56608 3.71903285443165E-11 +71264 2.44342543952498E-11 +89716 1.60528790245929E-11 +112940 1.05473953266337E-11 +142190 6.92878919698013E-12 +179010 4.55189794598097E-12 +225360 2.99049455162931E-12 +283710 1.96470016335954E-12 +357170 1.29075751310548E-12 +449650 8.47996617880111E-13 +566080 5.57104768588322E-13 +712640 3.66015331637543E-13 +897160 2.40462986334895E-13 + diff --git a/data/diff_spectra/e-.dat b/data/diff_spectra/e-.dat new file mode 100644 index 0000000..28a9e9a --- /dev/null +++ b/data/diff_spectra/e-.dat @@ -0,0 +1,81 @@ +0.011294 0.002689187394332 +0.014219 0.002579048978592 +0.017901 0.002467476429373 +0.022536 0.002354051775208 +0.028371 0.002238402116545 +0.035717 0.00212023832646 +0.044965 0.001999400281882 +0.056607 0.00187589217173 +0.071264 0.001749910781723 +0.089717 0.00162190868036 +0.11294 0.001492654913588 +0.14219 0.001363040557935 +0.17901 0.001234384293589 +0.22536 0.001108104910314 +0.28371 0.000985713600424 +0.35717 0.000868711425533 +0.44965 0.000758478774442 +0.56608 0.000656154217899 +0.71264 0.000562584564949 +0.89717 0.000478232275623 +1.1294 0.000403265867032 +1.4219 0.000337446547504 +1.7901 0.000280379533019 +2.2536 0.000231429945562 +2.8371 0.000189843772937 +3.5717 0.000154812831942 +4.4965 0.000125525825465 +5.6607 0.000101202540635 +7.1265 8.11159983538443E-05 +8.9717 6.46177235973272E-05 +11.295 5.11296864248236E-05 +14.219 4.01596232582779E-05 +17.901 3.12774113726374E-05 +22.536 2.41290066381283E-05 +28.371 1.84142984652614E-05 +35.717 1.38832606679915E-05 +44.965 1.03272751735292E-05 +56.607 7.57083177578504E-06 +71.265 5.46470621078735E-06 +89.716 3.88220981178845E-06 +112.94 2.71441697341347E-06 +142.19 1.86834677874852E-06 +179.01 1.26732441647693E-06 +225.36 8.48174358283652E-07 +283.71 5.60861635094641E-07 +357.17 3.66988279909981E-07 +449.65 2.37978852527483E-07 +566.08 1.53153816272833E-07 +712.65 9.79490766465823E-08 +897.16 6.23234400034651E-08 +1129.4 3.94935618006647E-08 +1421.9 2.49380335616817E-08 +1790.1 1.57059476488079E-08 +2253.6 9.87103224260283E-09 +2837.1 6.19350083057176E-09 +3571.7 3.88088380776872E-09 +4496.5 2.4292664525271E-09 +5660.8 1.51935125275659E-09 +7126.5 9.49671541644838E-10 +8971.7 5.93296269893906E-10 +11294 3.70554491999807E-10 +14219 2.31313680482007E-10 +17901 1.44368910374307E-10 +22536 9.00913405951646E-11 +28371 5.62125043564442E-11 +35717 3.50694120677042E-11 +44965 2.18769679710806E-11 +56608 1.36460987201958E-11 +71264 8.51194404628308E-12 +89716 5.30903770775794E-12 +112940 3.31156606446165E-12 +142190 2.0651471837211E-12 +179010 1.28791346960435E-12 +225360 8.03218055899891E-13 +283710 5.00931728152928E-13 +357170 3.12402393643133E-13 +449650 1.9482667420574E-13 +566080 1.21498978209913E-13 +712640 7.57734559007221E-14 +897160 4.72547019216388E-14 + diff --git a/data/diff_spectra/gamma.dat b/data/diff_spectra/gamma.dat new file mode 100644 index 0000000..f52c2fe --- /dev/null +++ b/data/diff_spectra/gamma.dat @@ -0,0 +1,81 @@ +1.13E-02 1.87E-03 +1.42E-02 5.78E-03 +1.79E-02 1.79E-02 +2.25E-02 5.51E-02 +2.84E-02 1.66E-01 +3.57E-02 4.56E-01 +4.50E-02 9.00E-01 +5.66E-02 1.01E+00 +7.13E-02 7.58E-01 +8.97E-02 5.04E-01 +1.13E-01 3.27E-01 +1.42E-01 2.12E-01 +1.79E-01 1.38E-01 +2.25E-01 9.09E-02 +2.84E-01 6.04E-02 +3.57E-01 4.06E-02 +4.50E-01 2.77E-02 +5.66E-01 6.98E-02 +7.13E-01 1.34E-02 +8.97E-01 5.60E-03 +1.13E+00 6.97E-03 +1.42E+00 5.13E-03 +1.79E+00 3.84E-03 +2.25E+00 2.90E-03 +2.84E+00 2.22E-03 +3.57E+00 1.71E-03 +4.50E+00 1.32E-03 +5.66E+00 1.03E-03 +7.13E+00 7.99E-04 +8.97E+00 6.18E-04 +1.13E+01 4.74E-04 +1.42E+01 3.59E-04 +1.79E+01 2.67E-04 +2.25E+01 1.94E-04 +2.84E+01 1.37E-04 +3.57E+01 9.42E-05 +4.50E+01 6.26E-05 +5.66E+01 4.04E-05 +7.13E+01 2.53E-05 +8.97E+01 1.55E-05 +1.13E+02 9.33E-06 +1.42E+02 5.52E-06 +1.79E+02 3.23E-06 +2.25E+02 1.87E-06 +2.84E+02 1.08E-06 +3.57E+02 6.17E-07 +4.50E+02 3.53E-07 +5.66E+02 2.01E-07 +7.13E+02 1.14E-07 +8.97E+02 6.51E-08 +1.13E+03 3.70E-08 +1.42E+03 2.10E-08 +1.79E+03 1.19E-08 +2.25E+03 6.76E-09 +2.84E+03 3.83E-09 +3.57E+03 2.18E-09 +4.50E+03 1.23E-09 +5.66E+03 7.00E-10 +7.13E+03 3.97E-10 +8.97E+03 2.25E-10 +1.13E+04 1.28E-10 +1.42E+04 7.24E-11 +1.79E+04 4.10E-11 +2.25E+04 2.33E-11 +2.84E+04 1.32E-11 +3.57E+04 7.48E-12 +4.50E+04 4.24E-12 +5.66E+04 2.41E-12 +7.13E+04 1.36E-12 +8.97E+04 7.74E-13 +1.13E+05 4.39E-13 +1.42E+05 2.49E-13 +1.79E+05 1.41E-13 +2.25E+05 8.00E-14 +2.84E+05 4.54E-14 +3.57E+05 2.57E-14 +4.50E+05 1.46E-14 +5.66E+05 8.27E-15 +7.13E+05 4.69E-15 +8.97E+05 2.66E-15 + diff --git a/data/diff_spectra/mu+.dat b/data/diff_spectra/mu+.dat new file mode 100644 index 0000000..19a9f4a --- /dev/null +++ b/data/diff_spectra/mu+.dat @@ -0,0 +1,81 @@ +0.011294 1.26173569216985E-09 +0.014219 1.55890264199345E-09 +0.017901 1.92595052855896E-09 +0.022536 2.37929092970017E-09 +0.028371 2.93919634232651E-09 +0.035717 3.63067253816472E-09 +0.044965 4.48449587525947E-09 +0.056607 5.5385630991346E-09 +0.071264 6.83967248409842E-09 +0.089717 8.44530880769278E-09 +0.11294 1.04253103276171E-08 +0.14219 1.28679316007994E-08 +0.17901 1.58779302315174E-08 +0.22536 1.95847207638201E-08 +0.28371 2.41460947058135E-08 +0.35717 2.97535062073649E-08 +0.44965 3.66377211393377E-08 +0.56608 4.5076247736613E-08 +0.71264 5.53977437117546E-08 +0.89717 6.79939664126097E-08 +1.1294 8.33121051172514E-08 +1.4219 1.01885239856541E-07 +1.7901 1.24288131289989E-07 +2.2536 1.51159773156909E-07 +2.8371 1.83176612418543E-07 +3.5717 2.21021194793684E-07 +4.4965 2.65338025836637E-07 +5.6607 3.1668769116865E-07 +7.1265 3.75518250310106E-07 +8.9717 4.42129741325276E-07 +11.295 5.16782793107377E-07 +14.219 5.99804703719336E-07 +17.901 6.92027697774088E-07 +22.536 7.95038781353114E-07 +28.371 9.11611003187426E-07 +35.717 1.04561101659918E-06 +44.965 1.20120596986473E-06 +56.607 1.38120676315832E-06 +71.265 1.58490483764309E-06 +89.716 1.80613176605674E-06 +112.94 2.01675116545582E-06 +142.19 2.1984588701332E-06 +179.01 2.34893700020052E-06 +225.36 2.45634183429567E-06 +283.71 2.5140450295113E-06 +357.17 2.52063418388849E-06 +449.65 2.47864750070809E-06 +566.08 2.39288849433189E-06 +712.65 2.26905224451314E-06 +897.16 2.11294678152799E-06 +1129.4 1.93035847124502E-06 +1421.9 1.72713811975011E-06 +1790.1 1.50995604659241E-06 +2253.6 1.28624026829654E-06 +2837.1 1.06423097822524E-06 +3571.7 8.52519417530613E-07 +4496.5 6.59182801088131E-07 +5660.8 4.90681538258631E-07 +7126.5 3.50960367722511E-07 +8971.7 2.40945851540256E-07 +11294 1.58785018403949E-07 +14219 1.00509225737826E-07 +17901 6.12406959221397E-08 +22536 3.60126290669967E-08 +28371 2.05028771570566E-08 +35717 1.13401342176572E-08 +44965 6.11530800859797E-09 +56608 3.22633106214882E-09 +71264 1.67086453527603E-09 +89716 8.5181277652804E-10 +112940 4.28684184631739E-10 +142190 2.13357699128724E-10 +179010 1.05260351153269E-10 +225360 5.15586529965142E-11 +283710 2.5106495957919E-11 +357170 1.1238459063128E-11 +449650 4.95770202485376E-12 +566080 2.1793503911921E-12 +712640 9.55421835121602E-13 +897160 4.17888075003386E-13 + diff --git a/data/diff_spectra/mu-.dat b/data/diff_spectra/mu-.dat new file mode 100644 index 0000000..cdc50ee --- /dev/null +++ b/data/diff_spectra/mu-.dat @@ -0,0 +1,81 @@ +0.011294 1.23078100092017E-09 +0.014219 1.52042323137646E-09 +0.017901 1.87812688259201E-09 +0.022536 2.31986593255489E-09 +0.028371 2.86537041794303E-09 +0.035717 3.53897479636153E-09 +0.044965 4.37062672790963E-09 +0.056607 5.39719998832701E-09 +0.071264 6.6642272439789E-09 +0.089717 8.22763649404659E-09 +0.11294 1.01553731140714E-08 +0.14219 1.25333024264159E-08 +0.17901 1.54633486931837E-08 +0.22536 1.90714386602993E-08 +0.28371 2.35111337729491E-08 +0.35717 2.89687962058135E-08 +0.44965 3.5669123845335E-08 +0.56608 4.38824426266507E-08 +0.71264 5.39290906403059E-08 +0.89717 6.61911936156437E-08 +1.1294 8.11054087994195E-08 +1.4219 9.91928676891578E-08 +1.7901 1.21016493058529E-07 +2.2536 1.47203345475645E-07 +2.8371 1.78418820897792E-07 +3.5717 2.15335921742497E-07 +4.4965 2.58590889070848E-07 +5.6607 3.08734652934129E-07 +7.1265 3.66196491452731E-07 +8.9717 4.31233086716102E-07 +11.295 5.0400662683108E-07 +14.219 5.8464617233355E-07 +17.901 6.73620082956084E-07 +22.536 7.71925268027177E-07 +28.371 8.81479851474904E-07 +35.717 1.00507635805142E-06 +44.965 1.14576664363357E-06 +56.607 1.30552811967367E-06 +71.265 1.48349351412288E-06 +89.716 1.67433591064617E-06 +112.94 1.85024745989403E-06 +142.19 1.99578439334556E-06 +179.01 2.11291534712715E-06 +225.36 2.19222355437902E-06 +283.71 2.22869090438626E-06 +357.17 2.22163331627848E-06 +449.65 2.17360374543907E-06 +566.08 2.08897032604734E-06 +712.65 1.97278111544955E-06 +897.16 1.83013117383024E-06 +1129.4 1.66607213485201E-06 +1421.9 1.48568667928371E-06 +1790.1 1.29473833346287E-06 +2253.6 1.09958551856123E-06 +2837.1 9.07211776114866E-07 +3571.7 7.24818606842616E-07 +4496.5 5.59090376793188E-07 +5660.8 4.15277542078683E-07 +7126.5 2.96470603575589E-07 +8971.7 2.0321545317213E-07 +11294 1.33749076862655E-07 +14219 8.4577822726358E-08 +17901 5.14962564039684E-08 +22536 3.02675222222383E-08 +28371 1.72269491863213E-08 +35717 9.52688965168057E-09 +44965 5.13738516236392E-09 +56608 2.71056883624122E-09 +71264 1.40392870007439E-09 +89716 7.15838472899279E-10 +112940 3.60315301589689E-10 +142190 1.79361750286573E-10 +179010 8.85035594111962E-11 +225360 4.33578400196235E-11 +283710 2.11162447936965E-11 +357170 9.45261667163029E-12 +449650 4.17045860412233E-12 +566080 1.83350244924657E-12 +712640 8.03885096856871E-13 +897160 3.51639035184732E-13 + diff --git a/data/diff_spectra/neutron.dat b/data/diff_spectra/neutron.dat new file mode 100644 index 0000000..f83de9a --- /dev/null +++ b/data/diff_spectra/neutron.dat @@ -0,0 +1,80 @@ +1.13E-02 1.92E-02 +1.42E-02 1.57E-02 +1.79E-02 1.28E-02 +2.25E-02 1.05E-02 +2.84E-02 8.68E-03 +3.57E-02 7.20E-03 +4.50E-02 6.00E-03 +5.66E-02 5.03E-03 +7.13E-02 4.24E-03 +8.97E-02 3.60E-03 +1.13E-01 3.07E-03 +1.42E-01 2.64E-03 +1.79E-01 2.29E-03 +2.25E-01 1.99E-03 +2.84E-01 1.74E-03 +3.57E-01 1.53E-03 +4.50E-01 1.34E-03 +5.66E-01 1.18E-03 +7.13E-01 1.03E-03 +8.97E-01 8.94E-04 +1.13E+00 7.65E-04 +1.42E+00 6.43E-04 +1.79E+00 5.27E-04 +2.25E+00 4.20E-04 +2.84E+00 3.22E-04 +3.57E+00 2.38E-04 +4.50E+00 1.69E-04 +5.66E+00 1.17E-04 +7.13E+00 8.03E-05 +8.97E+00 5.64E-05 +1.13E+01 4.13E-05 +1.42E+01 3.17E-05 +1.79E+01 2.52E-05 +2.25E+01 2.08E-05 +2.84E+01 1.81E-05 +3.57E+01 1.66E-05 +4.50E+01 1.60E-05 +5.66E+01 1.57E-05 +7.13E+01 1.52E-05 +8.97E+01 1.39E-05 +1.13E+02 1.20E-05 +1.42E+02 9.64E-06 +1.79E+02 7.06E-06 +2.25E+02 4.65E-06 +2.84E+02 2.74E-06 +3.57E+02 1.45E-06 +4.50E+02 7.08E-07 +5.66E+02 3.30E-07 +7.13E+02 1.53E-07 +8.97E+02 7.43E-08 +1.13E+03 3.85E-08 +1.42E+03 2.13E-08 +1.79E+03 1.23E-08 +2.25E+03 7.27E-09 +2.84E+03 4.34E-09 +3.57E+03 2.60E-09 +4.50E+03 1.56E-09 +5.66E+03 9.32E-10 +7.13E+03 5.58E-10 +8.97E+03 3.34E-10 +1.13E+04 2.00E-10 +1.42E+04 1.19E-10 +1.79E+04 7.14E-11 +2.25E+04 4.27E-11 +2.84E+04 2.55E-11 +3.57E+04 1.53E-11 +4.50E+04 9.13E-12 +5.66E+04 5.46E-12 +7.13E+04 3.26E-12 +8.97E+04 1.95E-12 +1.13E+05 1.17E-12 +1.42E+05 6.99E-13 +1.79E+05 4.18E-13 +2.25E+05 2.50E-13 +2.84E+05 1.50E-13 +3.57E+05 8.98E-14 +4.50E+05 5.38E-14 +5.66E+05 3.22E-14 +7.13E+05 1.93E-14 +8.97E+05 1.16E-14 diff --git a/data/diff_spectra/proton.dat b/data/diff_spectra/proton.dat new file mode 100644 index 0000000..d10acba --- /dev/null +++ b/data/diff_spectra/proton.dat @@ -0,0 +1,80 @@ +1.13E-02 2.33E-07 +1.42E-02 2.19E-07 +1.79E-02 2.06E-07 +2.25E-02 1.94E-07 +2.84E-02 1.83E-07 +3.57E-02 1.73E-07 +4.50E-02 1.65E-07 +5.66E-02 1.58E-07 +7.13E-02 1.52E-07 +8.98E-02 1.48E-07 +1.13E-01 1.45E-07 +1.42E-01 1.44E-07 +1.79E-01 1.45E-07 +2.25E-01 1.48E-07 +2.84E-01 1.53E-07 +3.57E-01 1.60E-07 +4.50E-01 1.71E-07 +5.66E-01 1.85E-07 +7.13E-01 2.02E-07 +8.98E-01 2.24E-07 +1.13E+00 2.49E-07 +1.42E+00 2.79E-07 +1.79E+00 3.12E-07 +2.25E+00 3.51E-07 +2.84E+00 3.93E-07 +3.57E+00 4.39E-07 +4.50E+00 4.88E-07 +5.66E+00 5.39E-07 +7.13E+00 5.91E-07 +8.98E+00 6.43E-07 +1.13E+01 6.94E-07 +1.42E+01 7.42E-07 +1.79E+01 7.87E-07 +2.25E+01 8.26E-07 +2.84E+01 8.58E-07 +3.57E+01 8.81E-07 +4.50E+01 8.92E-07 +5.66E+01 8.86E-07 +7.13E+01 8.61E-07 +8.98E+01 8.12E-07 +1.13E+02 7.38E-07 +1.42E+02 6.43E-07 +1.79E+02 5.34E-07 +2.25E+02 4.23E-07 +2.84E+02 3.20E-07 +3.57E+02 2.33E-07 +4.50E+02 1.65E-07 +5.66E+02 1.14E-07 +7.13E+02 7.72E-08 +8.98E+02 5.17E-08 +1.13E+03 3.41E-08 +1.42E+03 2.17E-08 +1.79E+03 1.29E-08 +2.25E+03 6.34E-09 +2.84E+03 2.16E-09 +3.57E+03 6.59E-10 +4.50E+03 3.31E-10 +5.66E+03 2.19E-10 +7.13E+03 1.47E-10 +8.98E+03 9.59E-11 +1.13E+04 6.03E-11 +1.42E+04 3.69E-11 +1.79E+04 2.21E-11 +2.25E+04 1.29E-11 +2.84E+04 7.48E-12 +3.57E+04 4.26E-12 +4.50E+04 2.40E-12 +5.66E+04 1.33E-12 +7.13E+04 7.37E-13 +8.98E+04 4.05E-13 +1.13E+05 2.21E-13 +1.42E+05 1.20E-13 +1.79E+05 6.50E-14 +2.25E+05 3.51E-14 +2.84E+05 1.89E-14 +3.57E+05 1.01E-14 +4.50E+05 5.43E-15 +5.66E+05 2.90E-15 +7.13E+05 1.55E-15 +8.98E+05 8.29E-16 diff --git a/run.py b/run.py new file mode 100644 index 0000000..ecfc625 --- /dev/null +++ b/run.py @@ -0,0 +1,14 @@ +import os +import sys + +import subprocess + +if __name__ == '__main__': + print(sys.argv) + target = int(sys.argv[1]) + for item in os.listdir('./configs'): + path = os.path.join('./configs', item) + i = int(item.split('_')[0]) + if i == target: + retcode = subprocess.call(['./bin/TestEm1', path]) + sys.exit(retcode) diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..27b91ce --- /dev/null +++ b/run.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +source /usr/opt/root/bin/thisroot.sh +source /usr/opt/geant/share/Geant4-10.1.3/geant4make/geant4make.sh +python run.py $1 diff --git a/scripts/configs.py b/scripts/configs.py index 003f2b9..d5249cc 100644 --- a/scripts/configs.py +++ b/scripts/configs.py @@ -2,19 +2,39 @@ import os import os.path as osp +import ROOT as r + +import array import numpy as np __all__ = [ 'generate_configs' ] +particles = ['e-', 'e+', 'gamma', 'mu-', 'mu+', 'proton'] + +depths = [1.0, 0.05, 0.1, 0.2, 0.5, 0.75, 1.5, 2.0, 3.0, 5.0] + +def get_seeds(n, super_seed): + import random + random.seed(super_seed) + + numbers = [] + + while len(set(numbers)) != n: + numbers = [ + (random.randrange(int(1.0e+6)), random.randrange(int(1.0e+6))) + for _ in range(n) + ] + + return numbers def get_resourse(path, dir=True): here = osp.dirname(osp.abspath(__file__)) resourse = osp.abspath(osp.join(here, path)) assert osp.exists(resourse) and (osp.isdir if dir else osp.isfile)(resourse), \ - 'resourse %(what) [%(where)] does not seem like a %s' % dict( + 'resourse {what} [{where}] does not seem like a {what}'.format( where = resourse, what = 'directory' if dir else 'file' ) @@ -23,6 +43,51 @@ def get_resourse(path, dir=True): get_dir = lambda path: get_resourse(path, dir=True) get_file = lambda path: get_resourse(path, dir=False) +def get_spectrum(particle): + import ROOT as r + + try: + path = get_file(osp.join('../data/diff_spectra/', particle + '.dat')) + datfile = np.loadtxt(path) + except Exception as e: + datfile = np.loadtxt(particle) + raise e + + ns = np.arange(datfile.shape[0] + 1) + bins = 10.0 ** (ns / 10.0 - 2) + assert np.allclose(datfile[:, 0], (bins[1:] + bins[:-1]) / 2.0, rtol=1.0e-2, atol=0.0) + + ### crayfis-sim wants KeV, data provided in MeV + bins *= 1000.0 + # ROOT is picky and wants python array.array for TH1F constructor + binsx = array.array('d', bins) + h = r.TH1F("particleEnergy", particle, len(binsx)-1, binsx) + for i, rate in enumerate(datfile[:, 1]): + h.Fill( + (binsx[i] + binsx[i + 1]) / 2, + rate * (binsx[i + 1] - binsx[i]) / 1000.0 + ) + + return h + +def generate_spectra(particles=particles): + import ROOT as r + data_dir = get_dir('../data') + spectra_dir = osp.join(data_dir, 'background_spectra') + + try: + os.makedirs(spectra_dir) + except: + pass + + for particle in particles: + f_out = r.TFile(osp.join(spectra_dir, particle + '.root'), 'RECREATE') + h = get_spectrum(particle) + h.Write() + f_out.Close() + + return spectra_dir + def get_total_flux(path): import ROOT as r @@ -35,25 +100,32 @@ def get_total_flux(path): ]) -def generate_configs(output_dir, ngen=int(1.0e+5), pixDepth=1, pixWidth=1.5, npix=5000, spectra_path=None, jobs=1): - hist_dir = get_dir('../data/background_spectra') - hists = [ - osp.join(hist_dir, item) - for item in os.listdir(hist_dir) - if item.endswith('.root') - ] +def generate_configs(output_dir, ngen=int(1.0e+5), pixWidth=1.5, pixDepth=None, npix=5000, spectra_path=None, jobs=1): + if pixDepth is None: + pixDepth = depths + + print('Pixel depths: %s' % pixDepth) - particle_names = [ - osp.basename(hist)[:-len('.root')] for hist in hists + hist_dir = generate_spectra(particles=particles) + hists = [ + osp.join(hist_dir, p + '.root') + for p in particles ] fluxes = [ get_total_flux(hist) for hist in hists ] print("Total flux: %.3e" % np.sum(fluxes)) + print( + "Fluxes:\n %s" % '\n '.join([ + "%s: %.3e" % (particle, flux) + for particle, flux in zip(particles, fluxes) + ]) + ) + priors = [ flux / np.sum(fluxes) for flux in fluxes ] print( "Priors:\n %s" % '\n '.join([ "%s: %.3e" % (particle, prior) - for particle, prior in zip(particle_names, priors) + for particle, prior in zip(particles, priors) ]) ) @@ -67,53 +139,38 @@ def generate_configs(output_dir, ngen=int(1.0e+5), pixDepth=1, pixWidth=1.5, npi for hist in hists ] - configs = dict( - beamEnergy=-1, - particle_meta=[ - dict( - output=osp.join(output_dir, '%s_%04d' % (osp.basename(hist)[:-len('.root')], job)), - particle=particle_name, + for depth in pixDepth: + for particle, hist in zip(particles, runtime_hists): + for job in range(jobs): + name = '{particle}_{job:06d}_depth={depth}'.format(particle=particle, job=job, depth=depth) + config = dict( + beamEnergy=-1, + particle=particle, energyHisto=hist, - job=job + ngen=ngen, + pixDepth=depth, + pixWidth=pixWidth, + npix=npix, + output=osp.join(output_dir, name) ) - for particle_name, hist in zip(particle_names, runtime_hists) - for job in range(jobs) - ], - ngen=ngen, - pixDepth=pixDepth, - pixWidth=pixWidth, - npix=npix, - ) - return dict_product(configs) - -def get_seeds(n, super_seed): - import random - random.seed(super_seed) - - numbers = [] - - while len(set(numbers)) != n: - numbers = [ - (random.randrange(int(1.0e+6)), random.randrange(int(1.0e+6))) - for _ in range(n) - ] - - return numbers + yield name, config if __name__ == '__main__': import argparse import shutil as sh + generate_spectra() + parser = argparse.ArgumentParser(description='Generate configs for cosmic background simulation.') parser.add_argument('ngen', type=str, help='number of particles of each type to shoot') parser.add_argument('-o', '--output', default='./events/', type=str, help='simulation output directory') - parser.add_argument('-d', '--pixDepth', default=1.0, type=float, help='pixel depth') parser.add_argument('-w', '--pixWidth', default=1.5, type=float, help='pixel width') parser.add_argument('-n', '--npix', default=5000, type=float, help='linear size of the sensor') parser.add_argument('-r', '--runtime_spectra_path', default='data/background_spectra/', type=str, help='overrides path to spectra files') parser.add_argument('-s', '--super_seed', default=12345, type=int, help='seed to generate seeds') parser.add_argument('-j', '--jobs', default=1, type=int, help='split simulation between number of jobs (per particle type)') + parser.add_argument('-d', '--pixDepth', default=None, type=float, help='pixel depth (by default simulation enumerates a range of depths).') parser.add_argument('-c', '--configs_output', default='./configs/', type=str, help='output for the generated config files') args = parser.parse_args() @@ -130,25 +187,29 @@ def get_seeds(n, super_seed): configs = list(generate_configs( output_dir = args.output, ngen = args.ngen, - pixDepth = args.pixDepth, pixWidth = args.pixWidth, + pixDepth=[args.pixDepth] if args.pixDepth is not None else None, npix = args.npix, jobs=args.jobs, spectra_path=args.runtime_spectra_path )) + super_seed = args.super_seed + + for (_, values), (seed1, seed2) in zip(configs, get_seeds(len(configs), super_seed=super_seed)): + values['seed1'] = seed1 + values['seed2'] = seed2 + try: os.makedirs(args.configs_output) except OSError: pass - super_seed = args.super_seed - - for values, (seed1, seed2) in zip(configs, get_seeds(len(configs), super_seed=super_seed)): - particle = values['particle'] - job = values['job'] + for i, (name, values) in enumerate(configs): values['seed1'] = seed1 values['seed2'] = seed2 - with open(osp.join(args.configs_output, '%s_%04d.mac' % (particle, job)), 'w') as f: + path = osp.join(args.configs_output, '%09d_%s.mac' % (i, name)) + + with open(path, 'w') as f: f.write(config.substitute(values)) From 081e45d7459c2b86545a3e4b8e60dc8956b50c55 Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Fri, 2 Mar 2018 19:11:47 +0300 Subject: [PATCH 02/24] cleaned background spectra files --- data/background_spectra/e+.root | Bin 5479 -> 0 bytes data/background_spectra/e-.root | Bin 5484 -> 0 bytes data/background_spectra/gamma.root | Bin 5511 -> 0 bytes data/background_spectra/mu+.root | Bin 5498 -> 0 bytes data/background_spectra/mu-.root | Bin 5498 -> 0 bytes data/background_spectra/proton.root | Bin 5511 -> 0 bytes 6 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 data/background_spectra/e+.root delete mode 100644 data/background_spectra/e-.root delete mode 100644 data/background_spectra/gamma.root delete mode 100644 data/background_spectra/mu+.root delete mode 100644 data/background_spectra/mu-.root delete mode 100644 data/background_spectra/proton.root diff --git a/data/background_spectra/e+.root b/data/background_spectra/e+.root deleted file mode 100644 index bef22aecd97016c627aa7a8046d7456dc8f83301..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5479 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 ACIA2c diff --git a/data/background_spectra/e-.root b/data/background_spectra/e-.root deleted file mode 100644 index 74381ac132fa16b9c639cc799af4e281e865559d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5484 zcmbuDRZv`Amxh}Lf(7>g0fM^+=|J${5?nfjCXF}JxO*cX9yAc#g1dHr;Dq4r9^4%Q z3}5DAE@!6xQ?=^ss&m%b&$`(4uKmL8?VSODBQgL0@Cg7QwS5YVr#18`P@WLEraTZ+GaC!Iy^Gx^6DJ3#nKRs!2g=0_ z|CjtfNClw(OY@fq0Em5pNqUOEQ~&^p+yB-oM%2F@VY>g#=li!Kl-K{}qiHMf$>TYg z!kw+mY@u>?P`HH$5Xxn!f~kc8aK{9=qeLa*2x{NG>}|NB*jR~Ytw5fMAo#p~?YBKH zGsIZ)YA3{7ziIYhoOC!7p@~!DDF{kC3@2$0lci>g5HXNnOA>AxzYr51rI&6NC>`3( za5)saYMH)0T7J0q-8-B2s#vzar<0H9>7r-O4eghFKHkw4oUB1aA#X@bNkK~Exx(8k znodkg%`n7AZXV0)cmmGh%;t&;#}ViaAv3VV^0^F8QLqgQABKDiGi5h9=4G>^6Fz5U zcHT3Kr(mu}5(z>#T;j0g{D^<=umAJPzmH5_C4^4Bi04g+w6}!CWCv2>E-T!_gS3;M z(lCj9CJ!EzeZeEMcaQ9(2XpM#%@>-DJQz04=ex;|IG$t0Bx?f~N!XSyY@D)sMH%ml zEU`SV7IC|1o21)x_@9T3{_f*Ow4)AV6Px^bZrV4YEG3%_io}dxT+eJryrZ&18uXn9 zEv$N-8LJ7aeB_Bqgo&WGm9ZnGlK%;{5QA^`kL#_-H3EZ?IW5!AvA`*lu^AlXdBBR) z0h7h}L!7g6@tq4VS4uKnW8QFjPSbCQhwqVSWXJ)kQ*6E89lL2e-sDr<`Yh|a{H|0% zxE8t|Z=oBEZ7|#rm;lRy{-r_XS>C7v+q%fU+PBkm_(sQ%RghcDP`9+yMzot@gq1_& zJoH#l3s@WK?P9Q=U zPi;`KQnrwcqbGX5UXqPr?F9qsayE`N)uHd>R|%!e>K6opYpgXKRv}kGT`MX&7w??! zU7$wDMsjxd=HHj_K0|GOaIHrg2qW>T-7Eg3V^Q(%=A|1Dt;WH~w}te9&)a-$>qL&; zctYes2M>wdCg(YrcP4=pWS5{Q+OyCoo*eJdYYqX{(^>WKp+~OkJ9M+h$`yO&gGX*w z>TAC3np^2h(}q_+JIa;=RF)>Df1tiR{uD`fnwa+`Xlb^1r{o#?h1CN`c;->t&GXAG zi=2GAV8ewGWoN{Jir!3p^mc>3_RX%N#L3(pE+lG~$lkfkwRbj(NFY%;tEwaD`uak& z>2{WhZYLAwZ50dL(CObf_$+p4WP)tFJn7dsZuCk zi!${hfx76{Q$uNyfI9iCRs;j;J^>qF)Dhmk@Poj;13nP%mj6p?yi5BxHjYL!X1vDW zde2n+T|h&3TKMDuW2KO-N5?A=Y2{Co>OToC{##3d(g-l$ap1+ zb!DOL#3hXV)v7QKZIt0LAN%|( zLlm;dw3T1B+%xYR5*!P7$r=x1xjZXiz;tT}ewURPur`3UO>c+)BbqC}zW}+0RXJnG z3xSWbN2Hv0+dy83AZV%uj3Rb2&;HY|5o6-^ge$Zd)jvm&M45jV7|)dU(-2LlD+h&A z?|6*9pvIaC|HC$mJU7qcd)hFTTiR#t$gxNkF_rF!%UXf3g5*1#5i{I1sU+#pVmm>{ z!hcj}X*uLJ=C7Lvk;;tK9>gzd&aY&@G}CRWkLrbuo6mz^n~)Mz>3&sxocc-ks;oKG zCxyOCsln-zlaD4sht|OcYV(3lC=AXx zf0C+)YcMBS>UszwW^#IV)}my2uKUzc-6#U_7lY)PV_ zbF*j5Q9R0f!LH%uq0=9fmrcHC>e1F+ZObIVTi+|X2gWasZ=0Esuo{x3yKGY0Ce@C@ z2F&A-ImTv+D+(}t4INy-7|CtaU-;Q#a|hnSwX?BhC&z-fY_b97uUOeu~ zzA^S1yq_Hh%$#urQO=XWj_XwUJnUN*A8O007V^sSwy3N@H3?s)ZQrTddMdf#Gi%i; zTEHZb#kE$>J5^1P9Bbmb(e`KCG4n;9zYW#XyFMR<{G`n`IDiR;CvBcIT(qawBYg|HoC}B9 zri;+3vQgfqiYS_axLDa#d!x;m1Zne^1f$PHTR>*&{Gjz;zj|DY$4E)7nO2nGsxB%$ejWVUQsZ#Kr?$hEMBls{Tg|Ipy%8j3gqs7S;O22&T>y&+NyyM1HC>S{ zP4Jp)EWI&7ic+HeW?#w~F5oXQ-@SkOhaN z((gDgPr;^za|1fs%`kNrh|h6V~@4J1apP-vx=>|PZ4A~3q$}5^`lA) z;_oz%`o{-j1?d*wD=GAj%wZY^!D_~`!vn)aMW2o^Rya$ zo}{5oFDOB_g6?~S2Pk!(3(pbD={~1wYlv6`Kc5FoXkfRk%mKiykd~?-_5^6)R zRDtD=49rjrvaeG2JbtDt;>}(4k)u^c)@UN2++&aJZZgM)QWgh$N6e}*0^Hdu_&x@V zS(3OJ7f730E@4!53^Axr50N`rp^*&1-c6D;cs05;rtzI`qHF27u6ql%9~ze((UfLo zLHh@?naDG(N)8ZzCEq`}P7`q=V02xwN*kan>)?7)N^fE~Sanpa`;2rca3wWRIH?=- zPo4fZ-OHj6ZD!3n%1M3kd+*}bxtx0-px9_~nV$PC#DYfg{iW#JqF*UYjlT#VteS_w z0&s8jhD~z|&eriRKXp%{U>(^JoLAdhHGvYVUU4S4mp!Ix8+%X|WB8!XcapdM#LZ?+ z`ytWmGf}xvE&B0VDd$3YpU!RZF^3N%D-{I+UbdV+H^X~BZ(|Q6k}Hq9j1$7;vBOMf zwIyZd*u=jUSzY`nqtVRXe9SXLH?kH)Sh4dqqEIqyeltn_a;J|s7s-PNCKmc%57P{ zi$6DkKQY2Av7Zk2b`j54EGh`q46PItbjBMM7K&2DmQB?Qyzm#UjN>x6-<2SF!9P5=e>iLh zJS-Mr;I^m4yn;fwts1LCwj=ZH>v-IU4vJkoJsWab*rz?^)l9N*ljbESalWGCD}t$! zdL-pcjnnAD#DtrsbDE90+p=QLt4ZA{CE2a}7*Ky)7qq^3nWBCV*kQeborNJ>5nF-1 zZJhT|u%`w~{dGjSUB^g6aEz7D+YA+)+gsZqR`u(0+H*xagSAZe_6~CNEc?0m>qgbc zSZ`mDoSSVC(bEf|xz)r(}u6MMt|XYnj)?0E3yANxUYRQa5cMc@ttE z&2oum*dX3n#jk)WHh=#ggtN_>vxZBpMOk*S<`X5z z)E87TsT`mZW#uCK$sZcai_}SZbXKLmqQg!}m90Nv$I-}0DI3@JAc~zH78J)cb-nW! zrBSDzE8BLJ4@9kdC0e1BfOUk7$|VBfSb6&aIo~6MXeeCYGtI3F4mSbCIQm=rnb%3nE2E9KGjNxuLx*c(mfhG3wNy(}gO&AuzLJZJO#_ z)+#uw@N9}@Oz>QKQts35p!8+F!g6CE(7vpV?hd=~mqS$sc{8@v*WF=*w&#@&dNjpr z$)Y(tZvNj+H3*VvOZ)9&kE{q=Dtj3>iC2Lwj}a#`1kH~Vjr8Y1n!m|z3>$i67BWurdE;KyNjrX zHSXC&$(j;>zK$zXzL5o|J-s1yIEe50!UV_lOqcGcgb|e?y_e?3ud03dDOpQ+!u#Q@ z`QCXAs1M&uWd|d0WLj4Th8Q7KQ`SRH)`RzZhkn9}s;!R~9@K+%IC&siq6v9~u?~r9<_m7pezJqIjrNDDl8@1%25&AZeB)a6Vl>WF2Hw@BT;r$7T_K^dp5ie- zj!b!pAM7|f^mzTTOmeu>*Rg+269o`F$Yk@{EFwI?-kHHNek6K20~`j-t+?6N;I;~N zwXf~l7;_efIJEipQwD_J?pw)fPN_^cm9aSU<^akU9+9CxwERq?vUw`*C#rVjQCiV$ zk2CSeA1~*x(oQDOFE)IM&JymjkIxmp6bf>FQ>43~P7>l^bIa9KL{dS99-&QyIGR7B zc0y)i1ss|jSst}ye3Zd8z*tat?qX5NtVIq(co(nc5*ZJo=)F%sgK0 zOh-66DQcW2X*1Q()@eK^6G4=B>o3(5_J|=X5caa98^`ipuARc1A3(0ZPycB;kNs;2 z3jLkg|5}1irrY0{{Xet>pNc$P0REr;+*1 diff --git a/data/background_spectra/gamma.root b/data/background_spectra/gamma.root deleted file mode 100644 index 117636a2cbff54b259d757051d887a465e8e6a0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5511 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 R5&tpKH4meYm&AL(e*s4gA4dQH diff --git a/data/background_spectra/mu-.root b/data/background_spectra/mu-.root deleted file mode 100644 index fb91d50dcdefe4613231908156d7f394c9b4023d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5498 zcmbuDWmJ^Wx5kGUVvx>J6a?vR36++R?igU`9vr%)M?e}Kx+Me!hHj7)q#3#yDM1<} z1TK0%+>iI(^?%pe>pg3|@80LPKb-aK^T1&+4*+1F1^@t90|3;1cR_Wxw!I6iyGX_T z?*+jy06zlD5EdwA6VrvED6?FIkIsnYa1^&5G*1?^}-NA*=8tMV%vxHhX*}-9+uGZ%6ZZ=jPa44UP zCl4?DFZzFy3jqG*`NsqRB;Dbp-o-yI0Dvm=e`^*W`L`zm-+%dne|y4u`Zpg}S4lvT z#0?7faIkW=QE;_^+xg<$@fyD(Fu@1-5&(R#Vm}aS>TJ^VRX{~nLhaq86BJ6hvE&H) zSsGLJDP=l9*wMk*Tym`e zGa8^dwpHKsc1GK6*2P}qX68kf|9++rK4X;~8Md@_4H-C?aXwKbU-bzgZXzUTVCQ7| z%@W%zjm+*ure;)!khNAcw=82r^n`q!uq;_&8@Z8uBFjX&7E*d#0v5#ZXkx;L=!m$W2lKDDm~`)+^zNm)(Yxh zDMpizrdAGIi8D*Owk(o*3};r?iG0T;?eZpBu*?Q(td)_dr@DVV4jHe?{=v`hGvJ`& zBF9O$dS+h_QeLSa7GDy(Pib-4t#I9+>}jzS^r1drq;y5`moNM3g4f~K9bM>-}pjHH;;!?-}gg_<(A2oucd_2p1wgxb^e6kFH>A z+zZz=PBiaG%t(M%%A-abfQJ=G(v6yUS$7CnqWTYSjkdQ>x7DKD(!+_b=>|rVN-@QlCRGw`sgf`U7}1?t;@Acp-8RZ(sxF!bC^-{=_!o?8WZsGqGbTgbii z26=gr)Gc(AHtX$PeWvZ1xuuX!=xDe9GurMFAh2HDYYvu0jX28&+`vNGdFjsTfw#gA zx85>i9r3|(Wqj6W@s#c6r@ncy-VGF_yRwXQg?nRhJk3>XnajCbU(yUxe%2+OZ{HM; zxSgL2F7&W@266;uMtyibXtprjSCez&7IZ8X-_Hw!#jRy2L3qiNr!SIi5=%Q>z(}jcSKALE#ow%fJF0DmGb2!ilnoo!m_$Qx_O$cZJ0N1j_NL)iD)M!{1+p zh`8WQ0F~ZQRxfu%%u>KlvJFf28Y zkz1w^tFqN22 z?RLA}oqHzv`yfG5P&-c*c6iKpimbmPT@^^0)2gE*)-e3|I=ZIJO~$YrwY->opqgCa zUP!^Wwhi1-!bpL5J*ICfQQQw{Hz;sf+yEn$iJ3?J(cKeFQaL9e^lKTPnu%5$F{zuH zZS3`Krs4Uyy3s_I_@JR#r#LsW)y#;Zxr;*C1!~9I^KB7~XtkNWIPzVFqaUeDE#*qH zQtRo|V%Ry2&$I7`8$y}6_AuS9J`}1By)is7WH{2?m)$SXWhgh#_p$YZy5U&*Wov*h zgj-Igek1EAT`%Qcg{XdN&rI~Rd-&d?RN}9mLZ2!g2nCpBJ%dWdaNzkICMpq4(J#lU zTo`TZFhm<9V>7WBKW9?@BR~-pu8^VTyu*N#ec98;^i2@l*H7|n`^SPeVC`>EnRx~twm}lpHRS|+Ma7z2V(K?M!mV&)0RD*!HHuv0`y}G;Elg4_&C93@yr5&IP*2*w=d<*)y0x)JC^> zlV|X4Sv?;qc;t72o7QP5JlfK^uG@Z*_x7$RA|`R)CX(s)mH3!`r+arnqi0;FczE9d z9n|@7y^Jj%NVINWT}^ta4a0)?En0Kht=l*G)}VD8Bdtr5yk>QkwJe&3JBc9ogTkIq z<`z(MsM@O}asA{qed{>nVi_}B4Q>P{-y_v?LRfZkw+?UeTrZ@vow%T~Sk>_0tdG4- z)Rai*jZdMz>5zh=!-H#4Oi85##xsc%UFOBH7Ie<=`GA)2-;i>r%FO70sx19imH&<| z0BfM`D+hOvdpaI)8>ov7T-ntYMj;RLv~>1mbarrcva!BVfLtuzEBF@uA>UZvyI z)Q&8Vas#AvPhx|D#W)}9$wVFjD5MzWS>zdfwumU!B8sCAB<=R%>_nT-${!>&Obsrk zHM$3F?qvH9gCCr9Gq7uj%TAn!i`r}Mp#y6=ov93MdqC>`bs7zlGA6|NE_A$n9;*wG zry|eg81@@~(=4I+Z8evq%v;34xEq{H`6DGNwD$Wah7yDs7qyjGWSX8R6_7FxJuR2)WLpexbOm_dV#XM1LYqIW zL}QDwxm``T1rE*_2{qUNyI$90&E531UH#U#Uv{c_Q><$UNn#;Ov?cSE1t6(zMw{GD z<~CK3I|%$1$3lCcbFxAo(eGG|{TC(QDFc_gPu^U2M09QL8)EHxrbP@_cwy{ko9Ouj zBRlUY8+KJvi#C1#xEio3qxO5oeIuHZWMq3`+lGr9IIR5xU;czC?#12zM-j>`)?^^Ap~U~))PY+(#oHkd^xZ*s>_T}I9z!s9Rd1@lr~}-+Z@+y6+m|{-P8AJ z1_j~rxKd1MRTg!a(agjg>r`?{3RVidD{x0AK7|1FX)2wtz1W8^$ke_MQ4qB;iJoKX zrO=hMP%&hWWR4WxlA^y(X1M5+J$y=cBA81u4 zJSWKEil9j7tgf`&9LKY)qL0(h+q(rB%!s%G8^20vtjz>((qR+q+a+MGkEt2_%c%LW zUEMyt#biZ4?~=!uczcp$*@)Ff8mnv+k^*~EO8WC zA4oXh5s-uF)xYN&eErp!nZH^(oY7TkMpY`^K^Nzl_AAyqQY&Uh&Alr`GepGJB2c7=82pzzWv*jm;Tpw5eq$>#|ORT%7%OdpZ zR^R6-^m$c+Buq5KsD?9FS~#EjF|oZusAcPDy`OTcuev0bmxx~nM z=}Dq2AgMBhzQus5oTXtJC`L)X4xQ6#DA%-$60$*gmBD%bE9%k1#FK0MWb~Red@#*NK z1?Ix$lFl2{VrK0pYb|3Ef-J}1#yyttiFqvGb4AB}-CApS*=($oBV?()U2aQujf0tW zd*SlF?He&EH_LU|$JL+tbegO_eWDTK3YT(D7hap3_LNGx3D`e1Nx2L5(U#!W$AWWN zsT5OQoGEM{io$*^a4%Ur2yE0+@qEC;#Zee&-aAAx^V&iBhj8uyZWhre7kYA?hsAPW zu)IRgh}7NrE)xfvFIAkcrskTX3S>j2TviH>v<1Rg{pzOVDW8dtb)VI+u1Nrfa?X(a z<~cGK?H2s+6K<^vC}ub;>uz&6=?tDC&TC}ywxWY_!}IRcee)skB-anL+=R+m02D`X@K^HLCaqcH zrM8k>*92R1Sxege2Xbj#l4Yu@C9uh_n#+sy$d8N;p9kY2kEm50twD(oV(nBsY zQ%#G`MwwCF-NU1@NrnipJn>jJz$Ymd7&sxC8qRk*FewSDQA`hs$HBgYud(y@1M*v= zMIPD}W7@pwJgb`s5;1w15Y$@cvv5$?H$km~I#0C9mky4@&=~|yTf65D?`4}4*`)4| zM%nx2*m=Na**}6irRMf&tM8xr+0Mm$E(SiV^;&pZV#3vTf+~31$40{NtTbMOUh-%G zB`^$OeO;5GHkZ2!$t^yfVjCAek)2eq-U!QF7AP(^#m0txX=l6w6%V?hvT2(@4p~1( zjN0#2x*0qyT}u(q=kpH!bfig^!tlA@HDTX@yt%UP$vWjKcJpoY;S5>RExO_HNto6K z&1KRzfiD%?HJ>#dI3&F@6Wn)koZUMZ{}*@ZtA zo;#-_o@ZPnHCPm98rhMzO*9;(h5N?Q#v~Y%$Yon4%N5B2OU_>?p=_#tyb88B zf4qwtW%___ifZ;mJapNbieRCh7fYdu9XIT;F@2Pzz`X@D*ZEAh{@8Pq2gZ;6wSEku zb`_`O?cwjWM{?);<~3~s1s;}S2l`tcf@{vc zENR(qV+U-6)vU!3zwx&`&A?)&>%|v&9d#n~I;xqXyb|J~mML<*XHpzQ=)OX`)Jt>_ zbz)nf(fvTMqc_-}ZuCgf#S9cSUv!Z%z$uw$vO9uGIlzq_x;U+Plh|euuX+6H`^(zY zbJ7fj-z_!?e$V2+?nC)0Z(O-L4fulz&GUIPF`$8IiV(6JxjcTSMT8$DASYZdh{{0k zJC_k_8*!c^q`g8zJ*#62f6i`?h@lWRWkmkzx{ap#=mB(Hm5}@696Z8nvy6)dqAv$RVMk!txY32k=8)$cEn7AkXz$xwp$&!KvhUJc7kM7!D30-tX)2HR5!oY5)B`sL_08~ z-n1+fo2@UC1Jk8MqbC-JjGf>^uBRD0yHDijASgaw2Fo-?-r~y(MLsI)A+mp2;Hoqi z1W@SzW_UN9C;f8=MgPt0|J=bl_wC=z{-3&ocUA6g0RLa7?k>yr9}(z(i2k{vcejZD PnCOm&+Rt0$J>b6pEMph} diff --git a/data/background_spectra/proton.root b/data/background_spectra/proton.root deleted file mode 100644 index eb90c55f0950c9d7a5b8e3d78dfb866efdb46aa8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5511 zcmb`LWmHsAw8w|WA*4e1HTN=@`08K$@X( z_ddV<;jI5Ye;5?%3IH5a0000>0DwH=A)Y?0Z65;dAu=)l zbAdYv0N~XD&`g^=5}tyHcN65$&;SAL#}8lsN6!M_Zy_J!UQQK&>A%Vky8!@L+H$t` z5K%50r~`z{!OWA(65`Hf0W!I6*92VP;%T zFsLikkrVcp{{NT`!1_z|j|>1veSpe*h<|hd09p8d*D}thzn$Uw{>$h8+ZmeJ-+WAM zc^)}JCo`C}iWS>zy+D?oTSiRvO)UxVyg|sE1ACsy@069o@%`DC2Hc2B zF-uFB#y~+I)34rVy19Yzsoh{aa0WWj+r|5^k(93kAi+*%uw`U&2Rto}+UM!~OHju9 zY2>&XtEbg+v)VvO?e}i@=#ysUq=}zSbX+&_VgpDMXGGpC?hU@^5g~_37<${bV6&WX zZbEo127L`UVeO{CIY>_=+BM^#HQNnvNJ){kJsd58V~7+wJ&w!a?~wZ1aVtbmR=iIlJpAizd>8qkHGM7DOBbU0-l$3(BNLN; z7|kBt7vQMp=ol8ZxKOKwj*;vOs2OQyM_*+f124eNddzl`RM(q8WHL`Wu?TDymOd|9794hVH##6Y z{&arK^nEDnbdOSJgqRG+*wtEfFF#&b?EYv8xTs@ty+P_~+oyI{buzdoi!;P>GF_4S z8{Qq#)Lz0*cl4yYQOWb(>6_t=3YTKl{Rj8_`B!hyn;`|XLS=$L)zgMLK zz)n}I6u+nPQL9+J7^@K(MdAaA6PfK=k}A>tLT9zXebA2seyyV@k`k4sLyN(P^Fg|L z>I$tW(_?W|_~xuf_C!h1&HN6hJ|ce~c8rpI2WMsE zcFXR(Aih1{{#6Pd%cQ9rd>P4==!9lZyoes{1r3|?9D~rgV%(y#BuefKG zv8vm@OlFwwOWY;}=-^jkugPdmW?x0AWH)(B-Cov`uO$|ZwGiqUIpvux)ffI`^mK~m zDxGk~Szc(VTM(fS+&yb~X_$+iztw)8*XNwAxa%{OQ84MGq5L*z9F7lqvmX${As;?e z{HwEoS~|jNR;KaPX}7E5vdn%wLUP5o9_x`X_eS5Scf=JFcUa}QI%Ebg+ziWJuqmgf zXm=QBW6MHgheYebf%JiH3q|gD7dKU>O^f0m;wiri41l;6zlYqLC>9by{nqTfH7({k zHHGYbGiZEjNL7m|!!;MNoDzR_FgF&Yyp{3C72w`R;$}_GXo!&bx0|Kq7ii+JygcTm zI5>;w9_wgjx6r`AnWjCgxVZYBxysp5*Tjq7iYVW_)S(NF{|$X5P=X)kkr!4!P${#18=yF;uFK}jZ{e5*X{Ll z%wN*xsXVl!SJX`cF*2EmnJe7$kOYMGrmL7w;XmcE5jW(>zG)(uBB`_0QK~&$ltUZU%R|;v~^}^GQx3zs-)*NDEU<(jck&nA-3kZ&S%NK>70Kf0H6xzdS9} znN_yZ-1W5zaR4g$H=^4ad?sW6I5k#^s#;anjWh52HU|1InrWx|)WG&~RJ+r}GHb}h zRNA^o5q~`xP z&2UlyNcA;eEAHu!6Bx_%`IC8!ebee8>C_bFzNR4!}ctTL@-36g6v z{7WpUDNgh?mAq3gE@-X3G*C~OkacGGR7Re1TQP2O`}bAt&kd?0aC29Mnv$V1_1pI5QuC=rfEI#PMN6sFRID)A^cYM~n5XoiIi#Qe4Jr?s%!K%-$r67x`S17w zu*A|l<4iERamrjzC zzkl&G+xLz3d2B$SARD8OWaJruJ&e=$5#^m`bgS5;}3U5e_QBxhJ^Zx`Z2BdGt}7eJemy+4Nf@G{u25s?8i&tP0tyk zELYxW^dkM(^1{SBjpH9vBME#A%bM~pBwL=#=RIZ^5vmaR&axcZ>FKi8L|X1ukW(%w9c~2?{|r&>2o>-SzeN^~w1) z&vCKW+hBX!PT=RN_qVux!^+|>F2MjJlOI!}0^OQQ*Puz^Wk$KRl#?e$)PHid;wZ9W zCQ@#$y3r!+h*l~edBTG;6+)oZYThTz&&Bx zrf6_?JD+Ae7`N>6_QzoQv5(dvEb|%%^co01+_`060 zzyQowjwCZ0RfU}<6mv01ttxgAP!-RIJQu`AAuyIMMU@@8`^%Bd;rqLWT0WNVd$K|b~zgWFO4NxQ(I&y-42 zZd1fCIbfvOytah&0;}lP!u(mWjvf%b2_Cy&bJrWSjk&-bDsx4}dlAPYBjGP+{ znh=hxi8NV>x<1I+{6#?b#ff;QM)}~@!Y}Laoi%q`jS0cGK#Rr{rz%0a zd2gUK_eim%WvPxw6rXV~Ba|7o-&j=I;DA*-3bvC#%}5&)p)1iIViF%iLIaCeSPLvq zgl(~LiK%H-hqCp$4x2M_*Gos!yGu>TN+mj};@r{>V?81@V)j*Bx`PA)S9M7|llY9k z0jbkQyv8$O@cDrlRcy5K4fblr9+BG3J;qFlRMkg5(d3x^oy;|6p8WVH7X7N`R>QxL zaPEkuM!Q6cts_N4?nGRSiA>;zLfHE27|wTmppd1szTv=$`4$T9wWqiHh%gu0a>xjr z$Y`r-S0>=%_f7C1PNWU+;c(wi_(V(!PEt!W%b{BFbJ_FPe}9qZNfO?6P?ZYTX;}Z1 zBirv@1r#WTaFDQSW>Mf3d7 zF7Mqgr`@1G%f&bZovHE9Am*I5O*LV=F$K_iF3-`!Qa5k!#@tr6S#LR2(`I8clh-GQzIw$-Sv%Iqe5HkU#=A%z;Gd;vZfPM-B3h z)`l#s*ntK&iL@12Sc_(p) zPwfK)k2zkT%JSEL-E%Z)9O5_;5QCyd1snDAzFr$0V7$L$=s${ zk~baixIZP_TjY_^!KP*=`b zWNosIuNf+iq{t+!VBc!EWnqPlgVIJ9UC8?vgJ6k{pD8&WDSQP~vjzrs5zn`1%p0z> z7iT*rSRu;bX-{aR)7VAIl$460(_QMT%e2Y)47TONagk@_O7AU!AL*nem5l59!b@HL zEGbNC==v5cOJU65E7|u{48?Bxe6~d^1MBb`RZw3gHI7N>FYc2p(hfTG#!7z)y3I&6 zF1#FPs_y9-9hXYf52uzPnCJm`CdOjKpH0vZV1J1ovf$9bKw~69d7%ax9xUB)7o3j zQco(-bFf;aeuMT)O>NTFKZ$x=SB3h5Ymg5#;ehaoGn%J zjDne+>(W&gve&`cMaUVJNxpNbX<5skAsMSYMHR;A=+JK+40phyVW;X$$`+vQ*I#1> z9r#sFdUT~5DX(+6JOWG3)QM8)%YQf~9NQANR`oyMCS6Bwy^lVfBWk%vG%=osX#AwO zO&s9)R=HPKu5QaJ;*pWya)4nM2Wn<17_Zhij`Wv!tKyDG?|cl+AU$wTVa|WamtSyg z|0P^3{U)*LT~UUCHF5h?(^*=mR~%(*csoStnSs%I!6DNo?AGFrs5l3cn}FzcqsuYei-N&k-nj)k@xcO(f5p?Xa3Rlk5j}B}<$S z_D!7vt#1!W?aPnYh_VeuP=Sv7ivlBS4k)7`ZIlQP{t|-ydag%zLd=N9kkLnDYqfLq9NlYE91r8_Fezenu@)jkNGKe-Q~9x z4Vyi5-=86M8!-g_KIRwcXiQXnIQ-60=e*8Qtt1syU zg3(#}Ggvpf Date: Tue, 27 Mar 2018 16:42:50 +0300 Subject: [PATCH 03/24] ... --- .gitignore | 2 ++ Dockerfile | 15 +++++++++------ include/OutputManager.hh | 2 +- scripts/configs.py | 4 +++- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index cd5e796..4971bf6 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ configs/ events/ data/background_spectra/ + +.idea/ diff --git a/Dockerfile b/Dockerfile index a034253..c366787 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,6 +32,13 @@ RUN make -j8 RUN make install RUN rm -rf /usr/opt/geant_build +### Python + +RUN apt-get update +RUN apt-get install -y python-pip + +RUN pip install numpy + ### CRAYFIS-SIM COPY data/ /usr/app/data @@ -45,14 +52,10 @@ WORKDIR /usr/app/ RUN bash -c "export G4INSTALL=/usr/opt/geant/ && source /usr/opt/root/bin/thisroot.sh && source /usr/opt/geant/share/Geant4-10.1.3/geant4make/geant4make.sh && export G4G4WORKDIR=/usr/geant_workdir && make -j9" -RUN apt-get install -y python-pip - -RUN pip install numpy - WORKDIR /usr/app/ -RUN bash -c "source /usr/opt/root/bin/thisroot.sh && python scripts/configs.py 100 -j10 -o /output" +RUN bash -c "source /usr/opt/root/bin/thisroot.sh && python scripts/configs.py 10000 -n 3000 -j100 -o /output" COPY run.sh /usr/app/ COPY run.py /usr/app/ -CMD sh run.sh +CMD sh run.sh \ No newline at end of file diff --git a/include/OutputManager.hh b/include/OutputManager.hh index b59f05c..fecd569 100644 --- a/include/OutputManager.hh +++ b/include/OutputManager.hh @@ -9,7 +9,7 @@ // the config file and dynamically allocate, // but it's a big pain in the ass to get the // DetectorConstruction to communicate with this object :( -#define MAX_PIX 5001 +#define MAX_PIX 3001 class OutputManager { diff --git a/scripts/configs.py b/scripts/configs.py index d5249cc..85cb84c 100644 --- a/scripts/configs.py +++ b/scripts/configs.py @@ -166,7 +166,7 @@ def generate_configs(output_dir, ngen=int(1.0e+5), pixWidth=1.5, pixDepth=None, parser.add_argument('ngen', type=str, help='number of particles of each type to shoot') parser.add_argument('-o', '--output', default='./events/', type=str, help='simulation output directory') parser.add_argument('-w', '--pixWidth', default=1.5, type=float, help='pixel width') - parser.add_argument('-n', '--npix', default=5000, type=float, help='linear size of the sensor') + parser.add_argument('-n', '--npix', default=5000, type=int, help='linear size of the sensor') parser.add_argument('-r', '--runtime_spectra_path', default='data/background_spectra/', type=str, help='overrides path to spectra files') parser.add_argument('-s', '--super_seed', default=12345, type=int, help='seed to generate seeds') parser.add_argument('-j', '--jobs', default=1, type=int, help='split simulation between number of jobs (per particle type)') @@ -205,6 +205,8 @@ def generate_configs(output_dir, ngen=int(1.0e+5), pixWidth=1.5, pixDepth=None, except OSError: pass + print('There are total %d tasks.' % len(configs)) + for i, (name, values) in enumerate(configs): values['seed1'] = seed1 values['seed2'] = seed2 From 5a49ba9f0e86395c3816b58c9691d2f6d1bf4575 Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Mon, 2 Apr 2018 16:12:02 +0300 Subject: [PATCH 04/24] ... --- Dockerfile | 8 ++++++-- data/config/run.mac.template | 25 +++++++++++++------------ geant_image.py | 2 +- scripts/configs.py | 19 +++++++------------ 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Dockerfile b/Dockerfile index c366787..0a214b5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,19 +14,23 @@ RUN tar xvfz root_v6.12.06.Linux-ubuntu16-x86_64-gcc5.4.tar.gz WORKDIR /usr/opt/root RUN apt-get install -y apt-utils cmake -RUN apt-get install -y libtbb2 g++ gcc +RUN apt-get install -y libtbb2 g++-4.7 gcc-4.7 RUN apt-get install -y python RUN apt-get install -y make RUN apt-get install -y python-dev +RUN apt-get update +RUN apt-get upgrade -y binutils + ### GEANT WORKDIR /usr/opt RUN wget http://geant4.web.cern.ch/geant4/support/source/geant4.10.01.p03.tar.gz -RUN tar xvfz geant4.10.01.p03.tar.gz WORKDIR /usr/opt/geant_build +ENV CXX g++-4.7 + RUN cmake -DCMAKE_INSTALL_PREFIX=/usr/opt/geant -DGEANT4_INSTALL_DATA=ON -DBUILD_SHARED_LIBS=ON /usr/opt/geant4.10.01.p03/ RUN make -j8 RUN make install diff --git a/data/config/run.mac.template b/data/config/run.mac.template index 6cf4083..5647f64 100644 --- a/data/config/run.mac.template +++ b/data/config/run.mac.template @@ -1,7 +1,7 @@ # example driver macro # beam energy in keV -/control/alias beamEnergy $beamEnergy +/control/alias beamEnergy 1300 # beam particle (gamma, mu-, e-, etc) /control/alias bParticle $particle @@ -27,11 +27,6 @@ /control/alias seed2 $seed2 /random/setSeeds {seed1} {seed2} -# set this to 1 if you want the beam -# angle to be randomly distributed -/control/alias doRandom 1 - - /control/verbose 2 /run/verbose 2 @@ -44,22 +39,28 @@ /testem/det/setDepth {pixDepth} um /testem/det/setNPix {npix} +# set this if you want to use cuts different from the default (0.5um) +#/testem/phys/setCuts 0.5 um /run/initialize /gun/particle {bParticle} -#/gun/energy {beamEnergy} keV -/testem/gun/rndm {doRandom} +/gun/energy -1 keV # uncomment the following line if you want the energy # to be sampled from a histogram. -# the file should contain a TH1F named "particleEnergy", -# with the desired distribution in units of keV. +# the file should contain a TH1F named "energy", +# with the desired distribution in units of MeV. + +/testem/gun/energy/hist $energyHisto -/testem/gun/energyHisto $energyHisto +# uncomment the following if you want the angle theta to be sampled +# from a histogram. When sampling theta, the angle phi will be uniformly +# distributed. The file should contain a TH1F named "theta" in units of radians. +/testem/gun/theta/hist data/theta_cos2.root # how often to print progress @@ -69,4 +70,4 @@ /analysis/setFileName $output # run the specified number of events -/run/beamOn {ngen} +/run/beamOn {ngen} \ No newline at end of file diff --git a/geant_image.py b/geant_image.py index 787ed98..01a3211 100644 --- a/geant_image.py +++ b/geant_image.py @@ -123,4 +123,4 @@ def random_composite(t, ntrack=20, trans=trans_linear): img = random_composite(t, ntrack=args.N, trans=trans_quant) img.save(args.output_file, format='jpeg', quality=98) - print "Saved to", args.output_file + print("Saved to", args.output_file) diff --git a/scripts/configs.py b/scripts/configs.py index 85cb84c..509bdb2 100644 --- a/scripts/configs.py +++ b/scripts/configs.py @@ -13,7 +13,7 @@ particles = ['e-', 'e+', 'gamma', 'mu-', 'mu+', 'proton'] -depths = [1.0, 0.05, 0.1, 0.2, 0.5, 0.75, 1.5, 2.0, 3.0, 5.0] +depths = [1, 1.5, 2, 2.5, 5, 7.5, 10, 15, 20, 30, 50] def get_seeds(n, super_seed): import random @@ -57,15 +57,13 @@ def get_spectrum(particle): bins = 10.0 ** (ns / 10.0 - 2) assert np.allclose(datfile[:, 0], (bins[1:] + bins[:-1]) / 2.0, rtol=1.0e-2, atol=0.0) - ### crayfis-sim wants KeV, data provided in MeV - bins *= 1000.0 # ROOT is picky and wants python array.array for TH1F constructor binsx = array.array('d', bins) - h = r.TH1F("particleEnergy", particle, len(binsx)-1, binsx) + h = r.TH1F("energy", particle, len(binsx)-1, binsx) for i, rate in enumerate(datfile[:, 1]): h.Fill( (binsx[i] + binsx[i + 1]) / 2, - rate * (binsx[i + 1] - binsx[i]) / 1000.0 + rate * (binsx[i + 1] - binsx[i]) ) return h @@ -116,7 +114,7 @@ def generate_configs(output_dir, ngen=int(1.0e+5), pixWidth=1.5, pixDepth=None, print("Total flux: %.3e" % np.sum(fluxes)) print( "Fluxes:\n %s" % '\n '.join([ - "%s: %.3e" % (particle, flux) + "%s: %.3e MeV" % (particle, flux) for particle, flux in zip(particles, fluxes) ]) ) @@ -139,9 +137,9 @@ def generate_configs(output_dir, ngen=int(1.0e+5), pixWidth=1.5, pixDepth=None, for hist in hists ] - for depth in pixDepth: - for particle, hist in zip(particles, runtime_hists): - for job in range(jobs): + for job in range(jobs): + for depth in pixDepth: + for particle, hist in zip(particles, runtime_hists): name = '{particle}_{job:06d}_depth={depth}'.format(particle=particle, job=job, depth=depth) config = dict( beamEnergy=-1, @@ -208,9 +206,6 @@ def generate_configs(output_dir, ngen=int(1.0e+5), pixWidth=1.5, pixDepth=None, print('There are total %d tasks.' % len(configs)) for i, (name, values) in enumerate(configs): - values['seed1'] = seed1 - values['seed2'] = seed2 - path = osp.join(args.configs_output, '%09d_%s.mac' % (i, name)) with open(path, 'w') as f: From 986024c00fd8ccd03504b4f5e78c385ec1f151de Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Mon, 2 Apr 2018 22:48:38 +0300 Subject: [PATCH 05/24] Docker files and more --- Dockerfile | 15 +++++++-------- data/config/run.mac.template | 2 +- scripts/configs.py | 6 +++--- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0a214b5..8d677b2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ RUN tar xvfz root_v6.12.06.Linux-ubuntu16-x86_64-gcc5.4.tar.gz WORKDIR /usr/opt/root RUN apt-get install -y apt-utils cmake -RUN apt-get install -y libtbb2 g++-4.7 gcc-4.7 +RUN apt-get install -y libtbb2 g++ gcc RUN apt-get install -y python RUN apt-get install -y make RUN apt-get install -y python-dev @@ -26,11 +26,10 @@ RUN apt-get upgrade -y binutils WORKDIR /usr/opt RUN wget http://geant4.web.cern.ch/geant4/support/source/geant4.10.01.p03.tar.gz +RUN tar -xzf geant4.10.01.p03.tar.gz WORKDIR /usr/opt/geant_build -ENV CXX g++-4.7 - RUN cmake -DCMAKE_INSTALL_PREFIX=/usr/opt/geant -DGEANT4_INSTALL_DATA=ON -DBUILD_SHARED_LIBS=ON /usr/opt/geant4.10.01.p03/ RUN make -j8 RUN make install @@ -45,10 +44,10 @@ RUN pip install numpy ### CRAYFIS-SIM -COPY data/ /usr/app/data -COPY include/ /usr/app/include -COPY src/ /usr/app/src -COPY scripts/ /usr/app/scripts +COPY data /usr/app/data +COPY include /usr/app/include +COPY src /usr/app/src +COPY scripts /usr/app/scripts COPY GNUmakefile /usr/app/ COPY TestEm1.cc /usr/app/ @@ -57,7 +56,7 @@ WORKDIR /usr/app/ RUN bash -c "export G4INSTALL=/usr/opt/geant/ && source /usr/opt/root/bin/thisroot.sh && source /usr/opt/geant/share/Geant4-10.1.3/geant4make/geant4make.sh && export G4G4WORKDIR=/usr/geant_workdir && make -j9" WORKDIR /usr/app/ -RUN bash -c "source /usr/opt/root/bin/thisroot.sh && python scripts/configs.py 10000 -n 3000 -j100 -o /output" +RUN bash -c "source /usr/opt/root/bin/thisroot.sh && python scripts/configs.py 1000000 -n 3000 -j1000 -o /output" COPY run.sh /usr/app/ COPY run.py /usr/app/ diff --git a/data/config/run.mac.template b/data/config/run.mac.template index 5647f64..d0bc4d1 100644 --- a/data/config/run.mac.template +++ b/data/config/run.mac.template @@ -1,7 +1,7 @@ # example driver macro # beam energy in keV -/control/alias beamEnergy 1300 +/control/alias beamEnergy 0 # beam particle (gamma, mu-, e-, etc) /control/alias bParticle $particle diff --git a/scripts/configs.py b/scripts/configs.py index 509bdb2..8a6f76b 100644 --- a/scripts/configs.py +++ b/scripts/configs.py @@ -90,7 +90,7 @@ def get_total_flux(path): import ROOT as r f = r.TFile(path) - h = f.Get('particleEnergy') + h = f.Get('energy') return np.sum([ h.GetBinContent(i) @@ -164,10 +164,10 @@ def generate_configs(output_dir, ngen=int(1.0e+5), pixWidth=1.5, pixDepth=None, parser.add_argument('ngen', type=str, help='number of particles of each type to shoot') parser.add_argument('-o', '--output', default='./events/', type=str, help='simulation output directory') parser.add_argument('-w', '--pixWidth', default=1.5, type=float, help='pixel width') - parser.add_argument('-n', '--npix', default=5000, type=int, help='linear size of the sensor') + parser.add_argument('-n', '--npix', default=3000, type=int, help='linear size of the sensor') parser.add_argument('-r', '--runtime_spectra_path', default='data/background_spectra/', type=str, help='overrides path to spectra files') parser.add_argument('-s', '--super_seed', default=12345, type=int, help='seed to generate seeds') - parser.add_argument('-j', '--jobs', default=1, type=int, help='split simulation between number of jobs (per particle type)') + parser.add_argument('-j', '--jobs', default=1000, type=int, help='split simulation between number of jobs (per particle type)') parser.add_argument('-d', '--pixDepth', default=None, type=float, help='pixel depth (by default simulation enumerates a range of depths).') parser.add_argument('-c', '--configs_output', default='./configs/', type=str, help='output for the generated config files') From e6842791d8f77203f3b162b43b391cc8b9e04b66 Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Thu, 12 Apr 2018 14:18:14 +0300 Subject: [PATCH 06/24] merged fixes from Chase --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8d677b2..bbc2652 100644 --- a/Dockerfile +++ b/Dockerfile @@ -56,9 +56,9 @@ WORKDIR /usr/app/ RUN bash -c "export G4INSTALL=/usr/opt/geant/ && source /usr/opt/root/bin/thisroot.sh && source /usr/opt/geant/share/Geant4-10.1.3/geant4make/geant4make.sh && export G4G4WORKDIR=/usr/geant_workdir && make -j9" WORKDIR /usr/app/ -RUN bash -c "source /usr/opt/root/bin/thisroot.sh && python scripts/configs.py 1000000 -n 3000 -j1000 -o /output" +RUN bash -c "source /usr/opt/root/bin/thisroot.sh && python scripts/configs.py 10000 -n 3000 -j1000 -o /output" COPY run.sh /usr/app/ COPY run.py /usr/app/ -CMD sh run.sh \ No newline at end of file +CMD sh run.sh From 0cbeac259af2abe02704a25b3c2792c6df6fabfb Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Thu, 3 May 2018 21:31:09 +0300 Subject: [PATCH 07/24] script for running locally --- .gitignore | 7 ++ Dockerfile | 12 ++- run.py | 5 +- run_local.py | 243 +++++++++++++++++++++++++++++++++++++++++++++++++ seg_wrapper.sh | 7 ++ 5 files changed, 270 insertions(+), 4 deletions(-) create mode 100644 run_local.py create mode 100644 seg_wrapper.sh diff --git a/.gitignore b/.gitignore index 4971bf6..7b61a1b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,10 @@ events/ data/background_spectra/ .idea/ + +cluster-submit.py +states/ + +run-local.sh +simlocal_log.txt +gdb_commands diff --git a/Dockerfile b/Dockerfile index bbc2652..62f7f21 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,7 +30,7 @@ RUN tar -xzf geant4.10.01.p03.tar.gz WORKDIR /usr/opt/geant_build -RUN cmake -DCMAKE_INSTALL_PREFIX=/usr/opt/geant -DGEANT4_INSTALL_DATA=ON -DBUILD_SHARED_LIBS=ON /usr/opt/geant4.10.01.p03/ +RUN cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/usr/opt/geant -DGEANT4_INSTALL_DATA=ON -DBUILD_SHARED_LIBS=ON /usr/opt/geant4.10.01.p03/ RUN make -j8 RUN make install RUN rm -rf /usr/opt/geant_build @@ -42,6 +42,9 @@ RUN apt-get install -y python-pip RUN pip install numpy +RUN apt-get install -y gdb +RUN apt-get install -y valgrind + ### CRAYFIS-SIM COPY data /usr/app/data @@ -51,14 +54,17 @@ COPY scripts /usr/app/scripts COPY GNUmakefile /usr/app/ COPY TestEm1.cc /usr/app/ +COPY gdb_commands /usr/app/ +COPY seg_wrapper.sh /usr/app/ + WORKDIR /usr/app/ RUN bash -c "export G4INSTALL=/usr/opt/geant/ && source /usr/opt/root/bin/thisroot.sh && source /usr/opt/geant/share/Geant4-10.1.3/geant4make/geant4make.sh && export G4G4WORKDIR=/usr/geant_workdir && make -j9" WORKDIR /usr/app/ -RUN bash -c "source /usr/opt/root/bin/thisroot.sh && python scripts/configs.py 10000 -n 3000 -j1000 -o /output" +RUN bash -c "source /usr/opt/root/bin/thisroot.sh && python scripts/configs.py 10000 -n 3000 -j10 -o /output" COPY run.sh /usr/app/ COPY run.py /usr/app/ -CMD sh run.sh +CMD sh run.sh \ No newline at end of file diff --git a/run.py b/run.py index ecfc625..a0ec571 100644 --- a/run.py +++ b/run.py @@ -10,5 +10,8 @@ path = os.path.join('./configs', item) i = int(item.split('_')[0]) if i == target: - retcode = subprocess.call(['./bin/TestEm1', path]) + retcode = subprocess.call([ + 'bash', 'seg_wrapper.sh', './bin/TestEm1', path + ]) + sys.exit(retcode) diff --git a/run_local.py b/run_local.py new file mode 100644 index 0000000..41184af --- /dev/null +++ b/run_local.py @@ -0,0 +1,243 @@ +import os +import os.path as osp + +import ROOT as r + +import array +import numpy as np + +__all__ = [ + 'generate_configs' +] + +particles = ['e-', 'e+', 'gamma', 'mu-', 'mu+', 'proton'] + +def get_seeds(n, super_seed): + import random + random.seed(super_seed) + + numbers = [] + + while len(set(numbers)) != n: + numbers = [ + (random.randrange(int(1.0e+6)), random.randrange(int(1.0e+6))) + for _ in range(n) + ] + + return numbers + +def get_resourse(path, dir=True): + here = osp.dirname(osp.abspath(__file__)) + + resourse = osp.abspath(osp.join(here, path)) + assert osp.exists(resourse) and (osp.isdir if dir else osp.isfile)(resourse), \ + 'resourse {what} [{where}] does not seem like a {what}'.format( + where = resourse, what = 'directory' if dir else 'file' + ) + + return resourse + +get_dir = lambda path: get_resourse(path, dir=True) +get_file = lambda path: get_resourse(path, dir=False) + +def get_spectrum(particle): + import ROOT as r + + try: + path = get_file(osp.join('./data/diff_spectra/', particle + '.dat')) + datfile = np.loadtxt(path) + except Exception as e: + raise e + + ns = np.arange(datfile.shape[0] + 1) + bins = 10.0 ** (ns / 10.0 - 2) + assert np.allclose(datfile[:, 0], (bins[1:] + bins[:-1]) / 2.0, rtol=1.0e-2, atol=0.0) + + # ROOT is picky and wants python array.array for TH1F constructor + binsx = array.array('d', bins) + h = r.TH1F("energy", particle, len(binsx)-1, binsx) + for i, rate in enumerate(datfile[:, 1]): + h.Fill( + (binsx[i] + binsx[i + 1]) / 2, + rate * (binsx[i + 1] - binsx[i]) + ) + + return h + +def generate_spectra(particles=particles): + import ROOT as r + data_dir = get_dir('./data') + spectra_dir = osp.join(data_dir, 'background_spectra') + + try: + os.makedirs(spectra_dir) + except: + pass + + for particle in particles: + f_out = r.TFile(osp.join(spectra_dir, particle + '.root'), 'RECREATE') + h = get_spectrum(particle) + h.Write() + f_out.Close() + + return spectra_dir + +def get_total_flux(path): + import ROOT as r + + f = r.TFile(path) + h = f.Get('energy') + + return np.sum([ + h.GetBinContent(i) + for i in range(h.GetSize()) + ]) + + +def generate_configs(output_dir, ngen, pixWidth, pixDepth, npix=5000, spectra_path=None, splits=1): + print('Pixel depths: %s' % pixDepth) + + hist_dir = generate_spectra(particles=particles) + hists = [ + osp.join(hist_dir, p + '.root') + for p in particles + ] + + fluxes = [ get_total_flux(hist) for hist in hists ] + print("Total flux: %.3e" % np.sum(fluxes)) + print( + "Fluxes:\n %s" % '\n '.join([ + "%s: %.3e MeV" % (particle, flux) + for particle, flux in zip(particles, fluxes) + ]) + ) + + priors = [ flux / np.sum(fluxes) for flux in fluxes ] + print( + "Priors:\n %s" % '\n '.join([ + "%s: %.3e" % (particle, prior) + for particle, prior in zip(particles, priors) + ]) + ) + + assert len(hists), 'there is no data for cosmic background spectra!' + + if spectra_path is None: + spectra_path = hist_dir + + runtime_hists = [ + osp.join(spectra_path, osp.basename(hist)) + for hist in hists + ] + + for job in range(splits): + for depth in pixDepth: + for particle, hist in zip(particles, runtime_hists): + name = '{particle}_{job:06d}_depth={depth}'.format(particle=particle, job=job, depth=depth) + config = dict( + beamEnergy=-1, + particle=particle, + energyHisto=hist, + ngen=ngen, + pixDepth=depth, + pixWidth=pixWidth, + npix=npix, + output=osp.join(output_dir, name) + ) + + yield name, config + +def worker(args): + from tempfile import NamedTemporaryFile + from subprocess import Popen, PIPE + import os + + template, (_, config) = args + + with NamedTemporaryFile(delete=False) as f: + f.write(template.substitute(config)) + tmpf = f.name + + executable = get_file('./bin/TestEm1') + + proc = Popen([executable, tmpf], stdout=PIPE, stderr=PIPE) + stdout, stderr = proc.communicate() + retcode = proc.returncode + + os.remove(tmpf) + + return retcode, stdout, stderr + +if __name__ == '__main__': + import argparse + + generate_spectra() + + parser = argparse.ArgumentParser(description='Runs craysim') + parser.add_argument('ngen', type=str, help='number of particles of each type to shoot') + parser.add_argument('-o', '--output', default='./events/', type=str, help='simulation output directory') + parser.add_argument('-w', '--pixWidth', default=1.5, type=float, help='pixel width') + parser.add_argument('-n', '--npix', default=3000, type=int, help='linear size of the sensor') + parser.add_argument('-r', '--runtime_spectra_path', default='data/background_spectra/', type=str, help='overrides path to spectra files') + parser.add_argument('-s', '--super_seed', default=12345, type=int, help='seed to generate seeds') + parser.add_argument('-t', '--tasks', default=1, type=int, help='number of task for each configuration') + parser.add_argument('-d', '--pixDepth', nargs='+', type=float, help='pixel depth (by default simulation enumerates a range of depths).') + parser.add_argument('-c', '--configs_output', default='./configs/', type=str, help='output for the generated config files') + parser.add_argument('-j', '--jobs', default=1, type=int, help='number of parallel processes') + + + args = parser.parse_args() + + try: + os.makedirs(args.output) + except OSError: + pass + + with open(get_file('./data/config/run.mac.template'), 'r') as _f: + from string import Template + template = Template(_f.read()) + + configs = list(generate_configs( + output_dir = args.output, + ngen = args.ngen, + pixWidth = args.pixWidth, + pixDepth=args.pixDepth, + npix = args.npix, + splits=args.tasks, + spectra_path=args.runtime_spectra_path + )) + + super_seed = args.super_seed + + for (_, values), (seed1, seed2) in zip(configs, get_seeds(len(configs), super_seed=super_seed)): + values['seed1'] = seed1 + values['seed2'] = seed2 + + try: + os.makedirs(args.configs_output) + except OSError: + pass + + print('There are total %d tasks.' % len(configs)) + + import tqdm + tqdm.monitor_interval = 0 + + from multiprocessing import Pool + + pool = Pool(processes=args.jobs) + + results = [] + + for result in tqdm.tqdm( + pool.imap(worker, zip([template] * len(configs), configs)), + total=len(configs) + ): + results.append(result) + + for retcode, stdout, stderr in results: + if retcode != 0: + print('Return code: %d;\nstdout:\n%s\nstderr:\n%s\n' % (retcode, stdout, stderr)) + + if all([ retcode == 0 for retcode, _, _ in results ]): + print('All processes finished successfully!') \ No newline at end of file diff --git a/seg_wrapper.sh b/seg_wrapper.sh new file mode 100644 index 0000000..4db4dfc --- /dev/null +++ b/seg_wrapper.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +ulimit -c unlimited +"$@" +if [[ $? -eq 139 ]]; then + gdb -q $1 core -x ~/backtrace +fi \ No newline at end of file From 367e1e95b21a7c7a26afe0beb0dd89ac70305f38 Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Sun, 2 Sep 2018 14:50:37 +0300 Subject: [PATCH 08/24] ... --- Dockerfile | 2 +- pycraysim/pycraysim/__init__.py | 2 + pycraysim/pycraysim/stream/__init__.py | 0 pycraysim/pycraysim/stream/simstream.py | 109 ++++++++++++++++++ pycraysim/pycraysim/utils/__init__.py | 2 + .../pycraysim/utils/args.py | 0 .../pycraysim/utils}/configs.py | 52 +++++++-- pycraysim/setup.py | 48 ++++++++ run-batch.py | 0 9 files changed, 206 insertions(+), 9 deletions(-) create mode 100644 pycraysim/pycraysim/__init__.py create mode 100644 pycraysim/pycraysim/stream/__init__.py create mode 100644 pycraysim/pycraysim/stream/simstream.py create mode 100644 pycraysim/pycraysim/utils/__init__.py rename scripts/utils.py => pycraysim/pycraysim/utils/args.py (100%) rename {scripts => pycraysim/pycraysim/utils}/configs.py (84%) create mode 100644 pycraysim/setup.py mode change 100755 => 100644 run-batch.py diff --git a/Dockerfile b/Dockerfile index 62f7f21..4cffd43 100644 --- a/Dockerfile +++ b/Dockerfile @@ -50,7 +50,7 @@ RUN apt-get install -y valgrind COPY data /usr/app/data COPY include /usr/app/include COPY src /usr/app/src -COPY scripts /usr/app/scripts +COPY pycraysim/pycraysim/utils /usr/app/scripts COPY GNUmakefile /usr/app/ COPY TestEm1.cc /usr/app/ diff --git a/pycraysim/pycraysim/__init__.py b/pycraysim/pycraysim/__init__.py new file mode 100644 index 0000000..b7b0605 --- /dev/null +++ b/pycraysim/pycraysim/__init__.py @@ -0,0 +1,2 @@ +from . import stream +from . import utils \ No newline at end of file diff --git a/pycraysim/pycraysim/stream/__init__.py b/pycraysim/pycraysim/stream/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pycraysim/pycraysim/stream/simstream.py b/pycraysim/pycraysim/stream/simstream.py new file mode 100644 index 0000000..cf9648c --- /dev/null +++ b/pycraysim/pycraysim/stream/simstream.py @@ -0,0 +1,109 @@ +import subprocess as sp + +from multiprocessing import Pool + +import os.path as osp + +from ..utils import get_config_template, get_binary, seed_stream + +from string import Template + +from itertools import izip, repeat + +import tempfile + +def sim_worker(args): + config, working_dir, seed, template = args + + workspace = tempfile.mkdtemp(dir=working_dir) + + if template is None: + template = get_config_template() + + config_path = osp.abspath(osp.join(workspace, 'run.mac')) + output_path = osp.abspath(osp.join(workspace, 'output.root')) + + config = config.copy() + config['output'] = output_path + config['seed1'] = seed[0] + config['seed2'] = seed[1] + + with open(config_path, 'w') as f: + f.write( + Template(template).safe_substitute(**config) + ) + + process = sp.Popen( + args=[config_path], + executable=get_binary(), + cwd=workspace, + stdin=sp.PIPE, + stdout=sp.PIPE, + stderr=sp.PIPE + ) + + stdout, stderr = process.communicate() + retcode = process.wait() + + if retcode == 0: + return config, stdout, stderr, workspace, output_path + else: + return config, stdout, stderr, workspace, None + +def default_copy(target_dir, config, stdout, stderr): + import shutil as sh + import json + + config = config.copy() + origin = config.pop('output', None) + try: + extension = origin.split('.')[-1] + except: + extension = '' + + props = sorted([ (k, v) for k, v in config.items() ], key=lambda x: x[0]) + name = '_'.join([ '%s=%s' % (k, v) for k, v in props ]) + target_path = osp.join(target_dir, name) + extension + + try: + sh.move(origin, target_path) + except Exception as e: + import warnings + warnings.warn(e.message) + + with open(target_path + '.json', 'w') as f: + json.dump(config, f) + + with open(target_path + '.stdout', 'w') as f: + f.write(stdout) + + with open(target_path + '.stderr', 'w') as f: + f.write(stderr) + + return target_path + +class SimStream(object): + def __init__(self, target_dir, configs, super_seed, copy_op=default_copy, num_workers=1): + self.template = get_config_template() + self.work_dir = tempfile.mkdtemp(prefix='craysim') + + self.seed_stream = seed_stream(super_seed) + self.pool = Pool(num_workers, maxtasksperchild=1) + + config_stream = izip( + configs, repeat(self.work_dir), self.seed_stream, self.template + ) + + self.result_stream = self.pool.imap(sim_worker, config_stream, chunksize=1) + self.copy_op = copy_op + self.target_dir = target_dir + + def stream(self): + for config, stdout, stderr, workspace, output_path in self.result_stream: + try: + yield self.copy_op(self.target_dir, config, stdout, stderr) + except Exception as e: + import warnings + warnings.warn(e.message) + warnings.warn(str(config)) + diff --git a/pycraysim/pycraysim/utils/__init__.py b/pycraysim/pycraysim/utils/__init__.py new file mode 100644 index 0000000..63e868c --- /dev/null +++ b/pycraysim/pycraysim/utils/__init__.py @@ -0,0 +1,2 @@ +from .configs import * +from .args import * \ No newline at end of file diff --git a/scripts/utils.py b/pycraysim/pycraysim/utils/args.py similarity index 100% rename from scripts/utils.py rename to pycraysim/pycraysim/utils/args.py diff --git a/scripts/configs.py b/pycraysim/pycraysim/utils/configs.py similarity index 84% rename from scripts/configs.py rename to pycraysim/pycraysim/utils/configs.py index 8a6f76b..a0907bb 100644 --- a/scripts/configs.py +++ b/pycraysim/pycraysim/utils/configs.py @@ -1,4 +1,4 @@ -from utils import dict_product +from args import dict_product import os import os.path as osp @@ -7,14 +7,25 @@ import array import numpy as np -__all__ = [ - 'generate_configs' -] - particles = ['e-', 'e+', 'gamma', 'mu-', 'mu+', 'proton'] depths = [1, 1.5, 2, 2.5, 5, 7.5, 10, 15, 20, 30, 50] +def seed_stream(super_seed): + import random + random.seed(super_seed) + + used_seeds= set() + + while True: + seed = (random.randrange(int(1.0e+6)), random.randrange(int(1.0e+6))) + + if seed in used_seeds: + continue + else: + used_seeds.add(seed) + yield seed + def get_seeds(n, super_seed): import random random.seed(super_seed) @@ -29,7 +40,7 @@ def get_seeds(n, super_seed): return numbers -def get_resourse(path, dir=True): +def get_resource(path, dir=True): here = osp.dirname(osp.abspath(__file__)) resourse = osp.abspath(osp.join(here, path)) @@ -40,8 +51,14 @@ def get_resourse(path, dir=True): return resourse -get_dir = lambda path: get_resourse(path, dir=True) -get_file = lambda path: get_resourse(path, dir=False) +get_dir = lambda path: get_resource(path, dir=True) +get_file = lambda path: get_resource(path, dir=False) + +def get_config_template(path='../data/config/run.mac.template'): + path = get_file(path) + + with open(path, 'r') as f: + return f.read() def get_spectrum(particle): import ROOT as r @@ -97,6 +114,25 @@ def get_total_flux(path): for i in range(h.GetSize()) ]) +def get_priors(data_root='../data', spectra_dir='background_spectra'): + spectra_path = osp.join(data_root, spectra_dir) + + flux = dict() + for particle in particles: + particle_flux = get_total_flux(osp.join(spectra_path, particle + '.root')) + flux[particle] = particle_flux + + total_flux = np.sum([ v for k, v in flux.values() ]) + + return dict([ + (k, v / total_flux) + for k, v in flux.items() + ]) + +BINARY = 'TestEm1' + +def get_binary(path='../bin'): + return get_file(osp.join(path, BINARY)) def generate_configs(output_dir, ngen=int(1.0e+5), pixWidth=1.5, pixDepth=None, npix=5000, spectra_path=None, jobs=1): if pixDepth is None: diff --git a/pycraysim/setup.py b/pycraysim/setup.py new file mode 100644 index 0000000..e32ffe1 --- /dev/null +++ b/pycraysim/setup.py @@ -0,0 +1,48 @@ +from setuptools import setup, find_packages + +from codecs import open +import os +import os.path as osp +import numpy as np + +setup( + name='craysim', + + version='0.1.1', + + description="""CRAYFIS simulation stream""", + + url='https://github.com/maxim-borisyak/crayfis-stream', + + author='Maxim Borisyak, Chase Shimmin', + author_email='mborisyak at hse dot ru', + + maintainer = 'Maxim Borisyak, Chase Shimmin', + maintainer_email = 'mborisyak at hse dot ru', + + license='MIT', + + classifiers=[ + 'Development Status :: 4 - Beta', + + 'Intended Audience :: Science/Research', + + 'License :: OSI Approved :: MIT License', + + 'Programming Language :: Python :: 3', + ], + + keywords='', + + packages=find_packages(where='pycraysim', exclude=['contrib', 'examples', 'docs', 'tests']), + + extras_require={ + 'dev': ['check-manifest'], + 'test': ['nose>=1.3.0'], + }, + + include_package_data=True, + + package_data = { + }, +) diff --git a/run-batch.py b/run-batch.py old mode 100755 new mode 100644 From 431eeb93382bb30c63ae00120ef08906df5916e8 Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Sun, 2 Sep 2018 14:57:05 +0300 Subject: [PATCH 09/24] .. --- .gitignore | 2 ++ pycraysim/setup.py | 7 +------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 7b61a1b..b535c17 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ states/ run-local.sh simlocal_log.txt gdb_commands + +craysim.egg-info/ \ No newline at end of file diff --git a/pycraysim/setup.py b/pycraysim/setup.py index e32ffe1..2cd03a0 100644 --- a/pycraysim/setup.py +++ b/pycraysim/setup.py @@ -1,10 +1,5 @@ from setuptools import setup, find_packages -from codecs import open -import os -import os.path as osp -import numpy as np - setup( name='craysim', @@ -34,7 +29,7 @@ keywords='', - packages=find_packages(where='pycraysim', exclude=['contrib', 'examples', 'docs', 'tests']), + packages=find_packages(where='.', exclude=['contrib', 'examples', 'docs', 'tests']), extras_require={ 'dev': ['check-manifest'], From 78a950ca298b86734d32c6fc00caf793cc110513 Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Sun, 2 Sep 2018 21:48:43 +0300 Subject: [PATCH 10/24] .. --- pycraysim/pycraysim/utils/configs.py | 44 +++++++++++++++------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/pycraysim/pycraysim/utils/configs.py b/pycraysim/pycraysim/utils/configs.py index a0907bb..b0a1b6b 100644 --- a/pycraysim/pycraysim/utils/configs.py +++ b/pycraysim/pycraysim/utils/configs.py @@ -1,15 +1,20 @@ -from args import dict_product import os import os.path as osp -import ROOT as r - import array import numpy as np particles = ['e-', 'e+', 'gamma', 'mu-', 'mu+', 'proton'] -depths = [1, 1.5, 2, 2.5, 5, 7.5, 10, 15, 20, 30, 50] +def get_package_root(): + path = osp.abspath(osp.dirname(__file__)) + + for i in range(3): + path = osp.split(path)[0] + + return path + +PACKAGE_ROOT = get_package_root() def seed_stream(super_seed): import random @@ -40,10 +45,9 @@ def get_seeds(n, super_seed): return numbers -def get_resource(path, dir=True): - here = osp.dirname(osp.abspath(__file__)) +def get_resource(paths, dir=True): + resourse = osp.abspath(osp.join(PACKAGE_ROOT, *paths)) - resourse = osp.abspath(osp.join(here, path)) assert osp.exists(resourse) and (osp.isdir if dir else osp.isfile)(resourse), \ 'resourse {what} [{where}] does not seem like a {what}'.format( where = resourse, what = 'directory' if dir else 'file' @@ -51,10 +55,10 @@ def get_resource(path, dir=True): return resourse -get_dir = lambda path: get_resource(path, dir=True) -get_file = lambda path: get_resource(path, dir=False) +get_dir = lambda *paths: get_resource(paths, dir=True) +get_file = lambda *paths: get_resource(paths, dir=False) -def get_config_template(path='../data/config/run.mac.template'): +def get_config_template(path='data/config/run.mac.template'): path = get_file(path) with open(path, 'r') as f: @@ -64,7 +68,8 @@ def get_spectrum(particle): import ROOT as r try: - path = get_file(osp.join('../data/diff_spectra/', particle + '.dat')) + path = get_file('data/diff_spectra/', particle + '.dat') + datfile = np.loadtxt(path) except Exception as e: datfile = np.loadtxt(particle) @@ -87,8 +92,8 @@ def get_spectrum(particle): def generate_spectra(particles=particles): import ROOT as r - data_dir = get_dir('../data') - spectra_dir = osp.join(data_dir, 'background_spectra') + + spectra_dir = get_dir('data', 'background_spectra') try: os.makedirs(spectra_dir) @@ -114,7 +119,7 @@ def get_total_flux(path): for i in range(h.GetSize()) ]) -def get_priors(data_root='../data', spectra_dir='background_spectra'): +def get_priors(data_root=get_dir('data'), spectra_dir='background_spectra'): spectra_path = osp.join(data_root, spectra_dir) flux = dict() @@ -131,13 +136,10 @@ def get_priors(data_root='../data', spectra_dir='background_spectra'): BINARY = 'TestEm1' -def get_binary(path='../bin'): - return get_file(osp.join(path, BINARY)) - -def generate_configs(output_dir, ngen=int(1.0e+5), pixWidth=1.5, pixDepth=None, npix=5000, spectra_path=None, jobs=1): - if pixDepth is None: - pixDepth = depths +def get_binary(): + return get_file('bin', BINARY) +def generate_configs(output_dir, ngen=int(1.0e+5), pixWidth=1.5, pixDepth=(1, ), npix=5000, spectra_path=None, jobs=1): print('Pixel depths: %s' % pixDepth) hist_dir = generate_spectra(particles=particles) @@ -214,7 +216,7 @@ def generate_configs(output_dir, ngen=int(1.0e+5), pixWidth=1.5, pixDepth=None, except OSError: pass - with open(get_file('../data/config/run.mac.template'), 'r') as _f: + with open(get_file('data/config/run.mac.template'), 'r') as _f: from string import Template config = Template(_f.read()) From 5c263556caadc552581248825ce4f88a6580c53e Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Sun, 2 Sep 2018 22:05:27 +0300 Subject: [PATCH 11/24] ... --- {data/config => config}/run.mac.template | 0 pycraysim/pycraysim/utils/configs.py | 7 +- run_local.py | 243 ----------------------- seg_wrapper.sh | 7 - 4 files changed, 4 insertions(+), 253 deletions(-) rename {data/config => config}/run.mac.template (100%) delete mode 100644 run_local.py delete mode 100644 seg_wrapper.sh diff --git a/data/config/run.mac.template b/config/run.mac.template similarity index 100% rename from data/config/run.mac.template rename to config/run.mac.template diff --git a/pycraysim/pycraysim/utils/configs.py b/pycraysim/pycraysim/utils/configs.py index b0a1b6b..d4332c3 100644 --- a/pycraysim/pycraysim/utils/configs.py +++ b/pycraysim/pycraysim/utils/configs.py @@ -58,7 +58,7 @@ def get_resource(paths, dir=True): get_dir = lambda *paths: get_resource(paths, dir=True) get_file = lambda *paths: get_resource(paths, dir=False) -def get_config_template(path='data/config/run.mac.template'): +def get_config_template(path='config/run.mac.template'): path = get_file(path) with open(path, 'r') as f: @@ -93,7 +93,8 @@ def get_spectrum(particle): def generate_spectra(particles=particles): import ROOT as r - spectra_dir = get_dir('data', 'background_spectra') + data_dir = get_dir('data') + spectra_dir = osp.join(data_dir, 'background_spectra') try: os.makedirs(spectra_dir) @@ -216,7 +217,7 @@ def generate_configs(output_dir, ngen=int(1.0e+5), pixWidth=1.5, pixDepth=(1, ), except OSError: pass - with open(get_file('data/config/run.mac.template'), 'r') as _f: + with open(get_config_template(), 'r') as _f: from string import Template config = Template(_f.read()) diff --git a/run_local.py b/run_local.py deleted file mode 100644 index 41184af..0000000 --- a/run_local.py +++ /dev/null @@ -1,243 +0,0 @@ -import os -import os.path as osp - -import ROOT as r - -import array -import numpy as np - -__all__ = [ - 'generate_configs' -] - -particles = ['e-', 'e+', 'gamma', 'mu-', 'mu+', 'proton'] - -def get_seeds(n, super_seed): - import random - random.seed(super_seed) - - numbers = [] - - while len(set(numbers)) != n: - numbers = [ - (random.randrange(int(1.0e+6)), random.randrange(int(1.0e+6))) - for _ in range(n) - ] - - return numbers - -def get_resourse(path, dir=True): - here = osp.dirname(osp.abspath(__file__)) - - resourse = osp.abspath(osp.join(here, path)) - assert osp.exists(resourse) and (osp.isdir if dir else osp.isfile)(resourse), \ - 'resourse {what} [{where}] does not seem like a {what}'.format( - where = resourse, what = 'directory' if dir else 'file' - ) - - return resourse - -get_dir = lambda path: get_resourse(path, dir=True) -get_file = lambda path: get_resourse(path, dir=False) - -def get_spectrum(particle): - import ROOT as r - - try: - path = get_file(osp.join('./data/diff_spectra/', particle + '.dat')) - datfile = np.loadtxt(path) - except Exception as e: - raise e - - ns = np.arange(datfile.shape[0] + 1) - bins = 10.0 ** (ns / 10.0 - 2) - assert np.allclose(datfile[:, 0], (bins[1:] + bins[:-1]) / 2.0, rtol=1.0e-2, atol=0.0) - - # ROOT is picky and wants python array.array for TH1F constructor - binsx = array.array('d', bins) - h = r.TH1F("energy", particle, len(binsx)-1, binsx) - for i, rate in enumerate(datfile[:, 1]): - h.Fill( - (binsx[i] + binsx[i + 1]) / 2, - rate * (binsx[i + 1] - binsx[i]) - ) - - return h - -def generate_spectra(particles=particles): - import ROOT as r - data_dir = get_dir('./data') - spectra_dir = osp.join(data_dir, 'background_spectra') - - try: - os.makedirs(spectra_dir) - except: - pass - - for particle in particles: - f_out = r.TFile(osp.join(spectra_dir, particle + '.root'), 'RECREATE') - h = get_spectrum(particle) - h.Write() - f_out.Close() - - return spectra_dir - -def get_total_flux(path): - import ROOT as r - - f = r.TFile(path) - h = f.Get('energy') - - return np.sum([ - h.GetBinContent(i) - for i in range(h.GetSize()) - ]) - - -def generate_configs(output_dir, ngen, pixWidth, pixDepth, npix=5000, spectra_path=None, splits=1): - print('Pixel depths: %s' % pixDepth) - - hist_dir = generate_spectra(particles=particles) - hists = [ - osp.join(hist_dir, p + '.root') - for p in particles - ] - - fluxes = [ get_total_flux(hist) for hist in hists ] - print("Total flux: %.3e" % np.sum(fluxes)) - print( - "Fluxes:\n %s" % '\n '.join([ - "%s: %.3e MeV" % (particle, flux) - for particle, flux in zip(particles, fluxes) - ]) - ) - - priors = [ flux / np.sum(fluxes) for flux in fluxes ] - print( - "Priors:\n %s" % '\n '.join([ - "%s: %.3e" % (particle, prior) - for particle, prior in zip(particles, priors) - ]) - ) - - assert len(hists), 'there is no data for cosmic background spectra!' - - if spectra_path is None: - spectra_path = hist_dir - - runtime_hists = [ - osp.join(spectra_path, osp.basename(hist)) - for hist in hists - ] - - for job in range(splits): - for depth in pixDepth: - for particle, hist in zip(particles, runtime_hists): - name = '{particle}_{job:06d}_depth={depth}'.format(particle=particle, job=job, depth=depth) - config = dict( - beamEnergy=-1, - particle=particle, - energyHisto=hist, - ngen=ngen, - pixDepth=depth, - pixWidth=pixWidth, - npix=npix, - output=osp.join(output_dir, name) - ) - - yield name, config - -def worker(args): - from tempfile import NamedTemporaryFile - from subprocess import Popen, PIPE - import os - - template, (_, config) = args - - with NamedTemporaryFile(delete=False) as f: - f.write(template.substitute(config)) - tmpf = f.name - - executable = get_file('./bin/TestEm1') - - proc = Popen([executable, tmpf], stdout=PIPE, stderr=PIPE) - stdout, stderr = proc.communicate() - retcode = proc.returncode - - os.remove(tmpf) - - return retcode, stdout, stderr - -if __name__ == '__main__': - import argparse - - generate_spectra() - - parser = argparse.ArgumentParser(description='Runs craysim') - parser.add_argument('ngen', type=str, help='number of particles of each type to shoot') - parser.add_argument('-o', '--output', default='./events/', type=str, help='simulation output directory') - parser.add_argument('-w', '--pixWidth', default=1.5, type=float, help='pixel width') - parser.add_argument('-n', '--npix', default=3000, type=int, help='linear size of the sensor') - parser.add_argument('-r', '--runtime_spectra_path', default='data/background_spectra/', type=str, help='overrides path to spectra files') - parser.add_argument('-s', '--super_seed', default=12345, type=int, help='seed to generate seeds') - parser.add_argument('-t', '--tasks', default=1, type=int, help='number of task for each configuration') - parser.add_argument('-d', '--pixDepth', nargs='+', type=float, help='pixel depth (by default simulation enumerates a range of depths).') - parser.add_argument('-c', '--configs_output', default='./configs/', type=str, help='output for the generated config files') - parser.add_argument('-j', '--jobs', default=1, type=int, help='number of parallel processes') - - - args = parser.parse_args() - - try: - os.makedirs(args.output) - except OSError: - pass - - with open(get_file('./data/config/run.mac.template'), 'r') as _f: - from string import Template - template = Template(_f.read()) - - configs = list(generate_configs( - output_dir = args.output, - ngen = args.ngen, - pixWidth = args.pixWidth, - pixDepth=args.pixDepth, - npix = args.npix, - splits=args.tasks, - spectra_path=args.runtime_spectra_path - )) - - super_seed = args.super_seed - - for (_, values), (seed1, seed2) in zip(configs, get_seeds(len(configs), super_seed=super_seed)): - values['seed1'] = seed1 - values['seed2'] = seed2 - - try: - os.makedirs(args.configs_output) - except OSError: - pass - - print('There are total %d tasks.' % len(configs)) - - import tqdm - tqdm.monitor_interval = 0 - - from multiprocessing import Pool - - pool = Pool(processes=args.jobs) - - results = [] - - for result in tqdm.tqdm( - pool.imap(worker, zip([template] * len(configs), configs)), - total=len(configs) - ): - results.append(result) - - for retcode, stdout, stderr in results: - if retcode != 0: - print('Return code: %d;\nstdout:\n%s\nstderr:\n%s\n' % (retcode, stdout, stderr)) - - if all([ retcode == 0 for retcode, _, _ in results ]): - print('All processes finished successfully!') \ No newline at end of file diff --git a/seg_wrapper.sh b/seg_wrapper.sh deleted file mode 100644 index 4db4dfc..0000000 --- a/seg_wrapper.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -ulimit -c unlimited -"$@" -if [[ $? -eq 139 ]]; then - gdb -q $1 core -x ~/backtrace -fi \ No newline at end of file From ab4c59f3948f328efd3026b79e2f9f54f046c7e1 Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Sun, 2 Sep 2018 22:27:50 +0300 Subject: [PATCH 12/24] ... --- pycraysim/pycraysim/stream/simstream.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pycraysim/pycraysim/stream/simstream.py b/pycraysim/pycraysim/stream/simstream.py index cf9648c..3d4d999 100644 --- a/pycraysim/pycraysim/stream/simstream.py +++ b/pycraysim/pycraysim/stream/simstream.py @@ -4,7 +4,7 @@ import os.path as osp -from ..utils import get_config_template, get_binary, seed_stream +from ..utils import get_config_template, get_binary, seed_stream, PACKAGE_ROOT from string import Template @@ -34,9 +34,8 @@ def sim_worker(args): ) process = sp.Popen( - args=[config_path], - executable=get_binary(), - cwd=workspace, + args=[get_binary(), config_path], + cwd=PACKAGE_ROOT, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE From 902ae45ee8b7bfcaa539eb33eb11002b23f5f73c Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Sun, 2 Sep 2018 22:29:21 +0300 Subject: [PATCH 13/24] ... --- pycraysim/pycraysim/stream/__init__.py | 1 + pycraysim/pycraysim/stream/simstream.py | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/pycraysim/pycraysim/stream/__init__.py b/pycraysim/pycraysim/stream/__init__.py index e69de29..cac411c 100644 --- a/pycraysim/pycraysim/stream/__init__.py +++ b/pycraysim/pycraysim/stream/__init__.py @@ -0,0 +1 @@ +from .simstream import * \ No newline at end of file diff --git a/pycraysim/pycraysim/stream/simstream.py b/pycraysim/pycraysim/stream/simstream.py index 3d4d999..016b58b 100644 --- a/pycraysim/pycraysim/stream/simstream.py +++ b/pycraysim/pycraysim/stream/simstream.py @@ -12,6 +12,11 @@ import tempfile +__all__ = [ + 'sim_worker', + 'SimStream' +] + def sim_worker(args): config, working_dir, seed, template = args From 16f96bbb74ba9b916553febf842c7c621212e4f7 Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Sun, 2 Sep 2018 22:38:16 +0300 Subject: [PATCH 14/24] ... --- pycraysim/pycraysim/stream/simstream.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pycraysim/pycraysim/stream/simstream.py b/pycraysim/pycraysim/stream/simstream.py index 016b58b..b16f6f0 100644 --- a/pycraysim/pycraysim/stream/simstream.py +++ b/pycraysim/pycraysim/stream/simstream.py @@ -71,9 +71,9 @@ def default_copy(target_dir, config, stdout, stderr): try: sh.move(origin, target_path) - except Exception as e: - import warnings - warnings.warn(e.message) + except: + import traceback + traceback.print_exc() with open(target_path + '.json', 'w') as f: json.dump(config, f) From 154e76d63deb40c5c3b26645f625b27a12194d91 Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Sun, 2 Sep 2018 22:43:09 +0300 Subject: [PATCH 15/24] ... --- pycraysim/pycraysim/stream/simstream.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pycraysim/pycraysim/stream/simstream.py b/pycraysim/pycraysim/stream/simstream.py index b16f6f0..bc24221 100644 --- a/pycraysim/pycraysim/stream/simstream.py +++ b/pycraysim/pycraysim/stream/simstream.py @@ -67,7 +67,7 @@ def default_copy(target_dir, config, stdout, stderr): props = sorted([ (k, v) for k, v in config.items() ], key=lambda x: x[0]) name = '_'.join([ '%s=%s' % (k, v) for k, v in props ]) - target_path = osp.join(target_dir, name) + extension + target_path = osp.join(target_dir, name) + '.' + extension try: sh.move(origin, target_path) @@ -107,7 +107,9 @@ def stream(self): try: yield self.copy_op(self.target_dir, config, stdout, stderr) except Exception as e: + import traceback import warnings - warnings.warn(e.message) + warnings.warn(str(config)) + traceback.print_exc() From be7a7476660ce82b7337ae00002b55855f936e6a Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Sun, 2 Sep 2018 22:51:47 +0300 Subject: [PATCH 16/24] ... --- pycraysim/pycraysim/stream/simstream.py | 5 ++++- pycraysim/pycraysim/utils/configs.py | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pycraysim/pycraysim/stream/simstream.py b/pycraysim/pycraysim/stream/simstream.py index bc24221..2d73141 100644 --- a/pycraysim/pycraysim/stream/simstream.py +++ b/pycraysim/pycraysim/stream/simstream.py @@ -95,7 +95,7 @@ def __init__(self, target_dir, configs, super_seed, copy_op=default_copy, num_wo self.pool = Pool(num_workers, maxtasksperchild=1) config_stream = izip( - configs, repeat(self.work_dir), self.seed_stream, self.template + configs, repeat(self.work_dir), self.seed_stream, repeat(self.template) ) self.result_stream = self.pool.imap(sim_worker, config_stream, chunksize=1) @@ -104,6 +104,9 @@ def __init__(self, target_dir, configs, super_seed, copy_op=default_copy, num_wo def stream(self): for config, stdout, stderr, workspace, output_path in self.result_stream: + if output_path is None: + raise Exception(stdout + '\n' + stderr) + try: yield self.copy_op(self.target_dir, config, stdout, stderr) except Exception as e: diff --git a/pycraysim/pycraysim/utils/configs.py b/pycraysim/pycraysim/utils/configs.py index d4332c3..112ec29 100644 --- a/pycraysim/pycraysim/utils/configs.py +++ b/pycraysim/pycraysim/utils/configs.py @@ -58,6 +58,8 @@ def get_resource(paths, dir=True): get_dir = lambda *paths: get_resource(paths, dir=True) get_file = lambda *paths: get_resource(paths, dir=False) +get_config_path = lambda : get_file('config/run.mac.template') + def get_config_template(path='config/run.mac.template'): path = get_file(path) @@ -217,7 +219,7 @@ def generate_configs(output_dir, ngen=int(1.0e+5), pixWidth=1.5, pixDepth=(1, ), except OSError: pass - with open(get_config_template(), 'r') as _f: + with open(get_config_path(), 'r') as _f: from string import Template config = Template(_f.read()) From 8291ed6232f065d3903517072dd07e7902ad2999 Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Sun, 2 Sep 2018 23:08:43 +0300 Subject: [PATCH 17/24] ... --- pycraysim/pycraysim/stream/simstream.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pycraysim/pycraysim/stream/simstream.py b/pycraysim/pycraysim/stream/simstream.py index 2d73141..e60ff83 100644 --- a/pycraysim/pycraysim/stream/simstream.py +++ b/pycraysim/pycraysim/stream/simstream.py @@ -26,7 +26,7 @@ def sim_worker(args): template = get_config_template() config_path = osp.abspath(osp.join(workspace, 'run.mac')) - output_path = osp.abspath(osp.join(workspace, 'output.root')) + output_path = osp.abspath(osp.join(workspace, 'output')) config = config.copy() config['output'] = output_path @@ -50,7 +50,7 @@ def sim_worker(args): retcode = process.wait() if retcode == 0: - return config, stdout, stderr, workspace, output_path + return config, stdout, stderr, workspace, output_path + '.root' else: return config, stdout, stderr, workspace, None @@ -59,7 +59,7 @@ def default_copy(target_dir, config, stdout, stderr): import json config = config.copy() - origin = config.pop('output', None) + origin = config.pop('output') + '.root' try: extension = origin.split('.')[-1] except: @@ -105,7 +105,7 @@ def __init__(self, target_dir, configs, super_seed, copy_op=default_copy, num_wo def stream(self): for config, stdout, stderr, workspace, output_path in self.result_stream: if output_path is None: - raise Exception(stdout + '\n' + stderr) + raise Exception(stdout + '\n\n' + stderr) try: yield self.copy_op(self.target_dir, config, stdout, stderr) @@ -116,3 +116,6 @@ def stream(self): warnings.warn(str(config)) traceback.print_exc() + def clean(self): + import shutil as sh + sh.rmtree(self.work_dir) \ No newline at end of file From 60d91da5da195d58bfd4ab1019283aa535544dc9 Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Sun, 2 Sep 2018 23:11:47 +0300 Subject: [PATCH 18/24] ... --- pycraysim/pycraysim/stream/simstream.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pycraysim/pycraysim/stream/simstream.py b/pycraysim/pycraysim/stream/simstream.py index e60ff83..d83db7d 100644 --- a/pycraysim/pycraysim/stream/simstream.py +++ b/pycraysim/pycraysim/stream/simstream.py @@ -65,6 +65,8 @@ def default_copy(target_dir, config, stdout, stderr): except: extension = '' + config.pop('energyHisto') + props = sorted([ (k, v) for k, v in config.items() ], key=lambda x: x[0]) name = '_'.join([ '%s=%s' % (k, v) for k, v in props ]) target_path = osp.join(target_dir, name) + '.' + extension From b1d772a59afc8f55dedf01a1ebc964b18577f682 Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Wed, 5 Sep 2018 17:07:57 +0300 Subject: [PATCH 19/24] ... --- pycraysim/pycraysim/stream/simstream.py | 52 +++++++++++++++++++++++-- pycraysim/scripts/craysim_job.py | 16 ++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 pycraysim/scripts/craysim_job.py diff --git a/pycraysim/pycraysim/stream/simstream.py b/pycraysim/pycraysim/stream/simstream.py index d83db7d..d76208b 100644 --- a/pycraysim/pycraysim/stream/simstream.py +++ b/pycraysim/pycraysim/stream/simstream.py @@ -2,6 +2,7 @@ from multiprocessing import Pool +import os import os.path as osp from ..utils import get_config_template, get_binary, seed_stream, PACKAGE_ROOT @@ -13,6 +14,7 @@ import tempfile __all__ = [ + 'sim_job', 'sim_worker', 'SimStream' ] @@ -54,7 +56,7 @@ def sim_worker(args): else: return config, stdout, stderr, workspace, None -def default_copy(target_dir, config, stdout, stderr): +def default_move(target_dir, config, stdout, stderr, retcode): import shutil as sh import json @@ -72,7 +74,8 @@ def default_copy(target_dir, config, stdout, stderr): target_path = osp.join(target_dir, name) + '.' + extension try: - sh.move(origin, target_path) + if retcode == 0: + sh.move(origin, target_path) except: import traceback traceback.print_exc() @@ -88,8 +91,51 @@ def default_copy(target_dir, config, stdout, stderr): return target_path +def sim_job(config): + config = config.copy() + workspace = tempfile.mkdtemp(prefix='crayfis-sim') + + try: + template = get_config_template() + + target_dir = config.pop('target') + + config_path = osp.abspath(osp.join(workspace, 'run.mac')) + output_path = osp.abspath(osp.join(workspace, 'output')) + + config['output'] = output_path + + with open(config_path, 'w') as f: + f.write( + Template(template).substitute(**config) + ) + + process = sp.Popen( + args=[get_binary(), config_path], + cwd=PACKAGE_ROOT, + stdin=sp.PIPE, + stdout=sp.PIPE, + stderr=sp.PIPE + ) + + stdout, stderr = process.communicate() + retcode = process.wait() + + default_move(target_dir, config, stdout, stderr, retcode) + except: + import traceback + traceback.print_exc() + finally: + try: + import shutil as sh + sh.rmtree(workspace) + except: + import traceback + traceback.print_exc() + + class SimStream(object): - def __init__(self, target_dir, configs, super_seed, copy_op=default_copy, num_workers=1): + def __init__(self, target_dir, configs, super_seed, copy_op=default_move, num_workers=1): self.template = get_config_template() self.work_dir = tempfile.mkdtemp(prefix='craysim') diff --git a/pycraysim/scripts/craysim_job.py b/pycraysim/scripts/craysim_job.py new file mode 100644 index 0000000..7a37a22 --- /dev/null +++ b/pycraysim/scripts/craysim_job.py @@ -0,0 +1,16 @@ +from pycraysim.stream import sim_job + +if __name__ == '__main__': + import sys + args = sys.argv[1:] + + config = dict() + + for arg in args: + tokens = arg.split('=') + assert len(tokens) == 2, 'arguments should be in form =' + + k, v = tokens + config[k] = v + + sim_job(config) \ No newline at end of file From 7fbd4f708ae4b781ca9bfcb39719f4d8a9c3ca2f Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Wed, 5 Sep 2018 17:12:19 +0300 Subject: [PATCH 20/24] ... --- pycraysim/scripts/craysim_job.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pycraysim/scripts/craysim_job.py b/pycraysim/scripts/craysim_job.py index 7a37a22..303fd5b 100644 --- a/pycraysim/scripts/craysim_job.py +++ b/pycraysim/scripts/craysim_job.py @@ -13,4 +13,4 @@ k, v = tokens config[k] = v - sim_job(config) \ No newline at end of file + sim_job(config) \ No newline at end of file From 78573a242cc0745b44bec28d64e659b7eded29fe Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Wed, 5 Sep 2018 17:22:29 +0300 Subject: [PATCH 21/24] ... --- pycraysim/pycraysim/stream/simstream.py | 36 ++++++++++++++++--------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/pycraysim/pycraysim/stream/simstream.py b/pycraysim/pycraysim/stream/simstream.py index d76208b..0cbe578 100644 --- a/pycraysim/pycraysim/stream/simstream.py +++ b/pycraysim/pycraysim/stream/simstream.py @@ -56,22 +56,25 @@ def sim_worker(args): else: return config, stdout, stderr, workspace, None +def naming(config): + config = config.copy() + + config.pop('energyHisto', None) + config.pop('output', None) + + props = sorted([(k, v) for k, v in config.items()], key=lambda x: x[0]) + name = '_'.join(['%s=%s' % (k, v) for k, v in props]) + return name + '.root' + + def default_move(target_dir, config, stdout, stderr, retcode): import shutil as sh import json config = config.copy() - origin = config.pop('output') + '.root' - try: - extension = origin.split('.')[-1] - except: - extension = '' + origin = config['output'] + '.root' - config.pop('energyHisto') - - props = sorted([ (k, v) for k, v in config.items() ], key=lambda x: x[0]) - name = '_'.join([ '%s=%s' % (k, v) for k, v in props ]) - target_path = osp.join(target_dir, name) + '.' + extension + target_path = osp.join(target_dir, config.pop('output')) try: if retcode == 0: @@ -93,13 +96,22 @@ def default_move(target_dir, config, stdout, stderr, retcode): def sim_job(config): config = config.copy() + try: + target_dir = config.pop('target') + target_name = naming(config) + + if osp.exists(osp.join(target_dir, target_name)): + return + except: + import traceback + traceback.print_exc() + return + workspace = tempfile.mkdtemp(prefix='crayfis-sim') try: template = get_config_template() - target_dir = config.pop('target') - config_path = osp.abspath(osp.join(workspace, 'run.mac')) output_path = osp.abspath(osp.join(workspace, 'output')) From 78a22a214606b2e734c3862756fbb8ffab1e8334 Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Wed, 5 Sep 2018 17:23:10 +0300 Subject: [PATCH 22/24] ... --- pycraysim/pycraysim/stream/simstream.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pycraysim/pycraysim/stream/simstream.py b/pycraysim/pycraysim/stream/simstream.py index 0cbe578..e90259c 100644 --- a/pycraysim/pycraysim/stream/simstream.py +++ b/pycraysim/pycraysim/stream/simstream.py @@ -101,7 +101,7 @@ def sim_job(config): target_name = naming(config) if osp.exists(osp.join(target_dir, target_name)): - return + print('Output file already exists. Skipping.') except: import traceback traceback.print_exc() From 8b883442ec6f3ee01d6fda159edc04926bb9907e Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Wed, 5 Sep 2018 17:23:46 +0300 Subject: [PATCH 23/24] ... --- pycraysim/pycraysim/stream/simstream.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pycraysim/pycraysim/stream/simstream.py b/pycraysim/pycraysim/stream/simstream.py index e90259c..19eacf1 100644 --- a/pycraysim/pycraysim/stream/simstream.py +++ b/pycraysim/pycraysim/stream/simstream.py @@ -102,6 +102,7 @@ def sim_job(config): if osp.exists(osp.join(target_dir, target_name)): print('Output file already exists. Skipping.') + return except: import traceback traceback.print_exc() From 31a6fb5206d3c6239f019b48af826221440f08b1 Mon Sep 17 00:00:00 2001 From: maxim-borisyak Date: Fri, 7 Sep 2018 01:56:18 +0300 Subject: [PATCH 24/24] ... --- pycraysim/pycraysim/stream/simstream.py | 24 ++++++++++++------------ pycraysim/pycraysim/utils/__init__.py | 5 ++++- pycraysim/pycraysim/utils/configs.py | 12 ++++++++++++ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/pycraysim/pycraysim/stream/simstream.py b/pycraysim/pycraysim/stream/simstream.py index 19eacf1..147f6c3 100644 --- a/pycraysim/pycraysim/stream/simstream.py +++ b/pycraysim/pycraysim/stream/simstream.py @@ -67,40 +67,40 @@ def naming(config): return name + '.root' -def default_move(target_dir, config, stdout, stderr, retcode): +def move(destination, config, stdout, stderr, retcode): import shutil as sh import json config = config.copy() origin = config['output'] + '.root' - target_path = osp.join(target_dir, config.pop('output')) - try: if retcode == 0: - sh.move(origin, target_path) + sh.move(origin, destination) + else: + raise Exception('Return code is not 0!') except: import traceback traceback.print_exc() - with open(target_path + '.json', 'w') as f: + with open(destination + '.json', 'w') as f: json.dump(config, f) - with open(target_path + '.stdout', 'w') as f: + with open(destination + '.stdout', 'w') as f: f.write(stdout) - with open(target_path + '.stderr', 'w') as f: + with open(destination + '.stderr', 'w') as f: f.write(stderr) - return target_path + return destination def sim_job(config): config = config.copy() try: target_dir = config.pop('target') - target_name = naming(config) + target_path = osp.join(target_dir, naming(config)) - if osp.exists(osp.join(target_dir, target_name)): + if osp.exists(target_path): print('Output file already exists. Skipping.') return except: @@ -134,7 +134,7 @@ def sim_job(config): stdout, stderr = process.communicate() retcode = process.wait() - default_move(target_dir, config, stdout, stderr, retcode) + move(target_path, config, stdout, stderr, retcode) except: import traceback traceback.print_exc() @@ -148,7 +148,7 @@ def sim_job(config): class SimStream(object): - def __init__(self, target_dir, configs, super_seed, copy_op=default_move, num_workers=1): + def __init__(self, target_dir, configs, super_seed, copy_op=move, num_workers=1): self.template = get_config_template() self.work_dir = tempfile.mkdtemp(prefix='craysim') diff --git a/pycraysim/pycraysim/utils/__init__.py b/pycraysim/pycraysim/utils/__init__.py index 63e868c..abcd374 100644 --- a/pycraysim/pycraysim/utils/__init__.py +++ b/pycraysim/pycraysim/utils/__init__.py @@ -1,2 +1,5 @@ from .configs import * -from .args import * \ No newline at end of file +from .args import * + +if not check_spectra(particles): + generate_spectra(particles) diff --git a/pycraysim/pycraysim/utils/configs.py b/pycraysim/pycraysim/utils/configs.py index 112ec29..9c78c21 100644 --- a/pycraysim/pycraysim/utils/configs.py +++ b/pycraysim/pycraysim/utils/configs.py @@ -92,6 +92,18 @@ def get_spectrum(particle): return h +def check_spectra(particles=particles): + try: + spectra_dir = get_dir('data', 'background_spectra') + + for particle in particles: + if not osp.exists(osp.join(spectra_dir, particle + '.root')): + return False + + return True + except: + return False + def generate_spectra(particles=particles): import ROOT as r