From 64d68c2a6817aab64ad52ad0fbf086952bc1ee19 Mon Sep 17 00:00:00 2001 From: Johannes Schumann <johannes.schumann@fau.de> Date: Tue, 17 Mar 2020 15:29:06 +0100 Subject: [PATCH] Tool for simulating and plotting the cc crosssection using oxygen target --- scripts/plot_cc_xsection.py | 136 ++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100755 scripts/plot_cc_xsection.py diff --git a/scripts/plot_cc_xsection.py b/scripts/plot_cc_xsection.py new file mode 100755 index 0000000..a225cb8 --- /dev/null +++ b/scripts/plot_cc_xsection.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python +# coding=utf-8 +# Filename: plot_cc_xsection.py +# Author: Johannes Schumann <jschumann@km3net.de> +""" +Generate + +Usage: + neutrino_jobcard_generator.py OUTFILE [--threads=<n>] [--verbose] + neutrino_jobcard_generator.py (-h | --help) + +Options: + -h --help Show this screen. + OUTFILE Filename for the output pdf containing the plot + --threads=<n> Number of worker threads which should be used to process data + parallel [default: 1] + --verbose Display GiBUU output +""" +import os +import time +import click +import numpy as np +import matplotlib.pyplot as plt +from thepipe.logger import get_logger +from tempfile import TemporaryDirectory +from os.path import dirname, abspath +from collections import defaultdict + +from concurrent.futures import ThreadPoolExecutor + +from km3buu.ctrl import run_jobcard +from km3buu.jobcard import Jobcard +from km3buu.jobcard import XSECTIONMODE_LOOKUP, PROCESS_LOOKUP, FLAVOR_LOOKUP +from km3buu.output import GiBUUOutput + + +def generate_neutrino_jobcard(process, flavor, energy, target): + """ + Generate a jobcard for neutrino interaction + + Parameters + ---------- + process: str + Interaction channel ["CC", "NC", "antiCC", "antiNC"] + flavour: str + Flavour ["electron", "muon", "tau"] + energy: float + Initial energy of the neutrino in GeV + target: (int, int) + (Z, A) describing the target nukleon + input_path: str + The input path pointing to the GiBUU lookup data which should be used + """ + jc = Jobcard() + # NEUTRINO + jc.set_property("neutrino_induced", "process_ID", + PROCESS_LOOKUP[process.lower()]) + jc.set_property("neutrino_induced", "flavor_ID", + FLAVOR_LOOKUP[flavor.lower()]) + jc.set_property("neutrino_induced", "nuXsectionMode", + XSECTIONMODE_LOOKUP["dSigmaMC"]) + jc.set_property("neutrino_induced", "includeDIS", True) + jc.set_property("neutrino_induced", "includeDELTA", True) + jc.set_property("neutrino_induced", "includeRES", True) + jc.set_property("neutrino_induced", "includeQE", True) + jc.set_property("neutrino_induced", "include1pi", True) + jc.set_property("neutrino_induced", "include2p2hQE", True) + jc.set_property("neutrino_induced", "include2pi", False) + jc.set_property("neutrino_induced", "include2p2hDelta", False) + jc.set_property("neutrino_induced", "printAbsorptionXS", "T") + jc.set_property("nl_SigmaMC", "enu", energy) + # INPUT + jc.set_property("input", "numTimeSteps", 0) + jc.set_property("input", "eventtype", 5) + jc.set_property("input", "numEnsembles", 1000) + jc.set_property("input", "delta_T", 0.2) + jc.set_property("input", "localEnsemble", True) + jc.set_property("input", "num_runs_SameEnergy", 1) + jc.set_property("input", "LRF_equals_CALC_frame", True) + # TARGET + jc.set_property("target", "target_Z", target[0]) + jc.set_property("target", "target_A", target[1]) + # MISC + # jc.set_property("nl_neutrinoxsection", "DISmassless", True) + jc.set_property("neutrinoAnalysis", "outputEvents", False) + jc.set_property("pythia", "PARP(91)", 0.44) + return jc + + +def worker(energy): + # create a neutrino jobcard for oxygen + tmpjc = generate_neutrino_jobcard("cc", "electron", energy, (8, 16)) + datadir = TemporaryDirectory(dir=dirname(__file__), + prefix="%sGeV" % energy) + run_jobcard(tmpjc, datadir.name) + data = GiBUUOutput(datadir.name) + return data + + +def main(): + from docopt import docopt + args = docopt(__doc__) + if args["--verbose"]: + log.setLevel("INFO") + log = get_logger("ctrl.py") + workers = int(args["--threads"]) + xsections = defaultdict(list) + energies = np.logspace(-1, 1, 50) + tasks = {} + with ThreadPoolExecutor(max_workers=workers) as executor: + for i, energy in enumerate(energies): + tasks[i] = executor.submit(worker, energy) + while True: + time.sleep(1) + status = {k: v.done() for k, v in tasks.items()} + click.clear() + for thr, st in status.items(): + click.echo("Thread %s (%s): %s" % (thr, energies[thr], st)) + if all(status.values()): + break + for i, res in tasks.items(): + data = res.result() + for k in ['sum', 'QE', 'highRES', 'DIS', 'Delta']: + xsections[k].append(data.xsection[k]) + for k in ['sum', 'QE', 'highRES', 'DIS', 'Delta']: + plt.plot(energies, np.divide(xsections[k], energies), label=k) + plt.xlabel("Energy [GeV]") + plt.ylabel("Crosssection") + plt.legend() + plt.xscale("log") + plt.grid() + plt.savefig(args["OUTFILE"]) + + +if __name__ == '__main__': + main() -- GitLab