From fdc19ae43d2ef54f7f1397b84d4f5cd7c1630fd5 Mon Sep 17 00:00:00 2001 From: Frank Sauerburger <frank@sauerburger.com> Date: Wed, 13 Jan 2021 20:59:02 +0100 Subject: [PATCH] Prune systematics as outermost wrapper --- uhepp-js/src/components/UheppHist.jsx | 4 +- uhepp-js/src/components/UheppHistUI.jsx | 158 ++++++++++++++++-------- uhepp-js/src/helpers/uhepp.js | 7 +- 3 files changed, 110 insertions(+), 59 deletions(-) diff --git a/uhepp-js/src/components/UheppHist.jsx b/uhepp-js/src/components/UheppHist.jsx index b4df53b..8790d52 100644 --- a/uhepp-js/src/components/UheppHist.jsx +++ b/uhepp-js/src/components/UheppHist.jsx @@ -484,7 +484,7 @@ const Legend = ({ showTotal, highlightedBin }) => { - const lineSkip = 16; + const lineSkip = -16; const mathSkip = 120; let i = 0 let legend = [] @@ -555,7 +555,7 @@ const Legend = ({ }) }) - return legend + return <Group top={-(i + 1) * lineSkip}>{legend}</Group> } const UheppHist = ({width, height, uhepp}) => { diff --git a/uhepp-js/src/components/UheppHistUI.jsx b/uhepp-js/src/components/UheppHistUI.jsx index f7fdd91..958f991 100644 --- a/uhepp-js/src/components/UheppHistUI.jsx +++ b/uhepp-js/src/components/UheppHistUI.jsx @@ -1,5 +1,6 @@ import React, { useState } from "react"; import UheppHist from "./UheppHist.jsx"; +import { objfilter, objmap } from "../helpers/uhepp.js"; const noVariationUsed = (uhepp) => { const main_names = uhepp.stacks.map(stack => stack.content.map(item => item.yields)).flat() @@ -56,70 +57,59 @@ const makeVariationRatio = (uhepp, stackId, variation, updown) => { }] } -const UheppHistUI = ({width, height, uhepp}) => { - const [uhepp_data, setData] = useState(uhepp) - const [envId, setEnvId] = useState(0) - const [envName, setEnvName] = useState("NOMINAL") +const UheppHistUIWithSyst = ({ + width, + height, + uhepp, + onEnvChange, + onEnvStackChange, + onReset, + isVariationReady, + variations, + origStacks, + envName, + envId, +}) => { + const [include_underflow, setUnderflow] = useState(!!uhepp.bins.include_underflow) + const [include_overflow, setOverflow] = useState(!!uhepp.bins.include_overflow) + const [rebin, setRebin] = useState(uhepp.bins.rebin || uhepp.bins.edges) + const [density_width, setDensity] = useState(uhepp.bins.density_width) const reset = () => { - setData(uhepp) - setEnvId(0) - setEnvName("NOMINAL") + setUnderflow(!!uhepp.bins.include_underflow) + setOverflow(!!uhepp.bins.include_overflow) + setRebin(uhepp.bins.rebin || uhepp.bins.edges) + setDensity(uhepp.bins.density_width) + onReset() } - const handleRebin = (e) => { let values = Array.from(e.target.selectedOptions, option => parseFloat(option.value)) - setData(Object.assign({}, uhepp_data, - {bins: Object.assign({}, uhepp_data.bins, {rebin: values})} - )) + setRebin(values) } + const handleUnderflow = (e) => { let value = e.target.checked - setData(Object.assign({}, uhepp_data, - {bins: Object.assign({}, uhepp_data.bins, {include_underflow: value})} - )) + setUnderflow(value) } const handleOverflow = (e) => { let value = e.target.checked - setData(Object.assign({}, uhepp_data, - {bins: Object.assign({}, uhepp_data.bins, {include_overflow: value})} - )) + setOverflow(value) } const handleDensityWidth = (e) => { let value = parseFloat(e.target.value) - setData(Object.assign({}, uhepp_data, - {bins: Object.assign({}, uhepp_data.bins, {density_width: value})} - )) + setDensity(value) } - const uhepp_data_env = envName == "NOMINAL" ? uhepp_data : Object.assign({}, uhepp_data, - {stacks: [ - ...uhepp.stacks, - ...makeVariationStacks(uhepp, envId, envName, "up"), - ...makeVariationStacks(uhepp, envId, envName, "down"), - ], - ratio: [ - ...makeVariationRatio(uhepp, envId, envName, "up"), - ...makeVariationRatio(uhepp, envId, envName, "down"), - ...uhepp.ratio, - ]}, - ) + const uhepp_derived = Object.assign({}, uhepp, + {bins: Object.assign({}, uhepp.bins, { + rebin: rebin.length > 1 ? rebin : (uhepp.bins.rebin), + include_underflow, + include_overflow, + density_width, + })}) - const handleEnvelop = (e) => { - let variationName = e.target.value - setEnvName(variationName) - } - const handleEnvStack = (e) => { - let stackId = parseInt(e.target.value) - setEnvId(stackId) - } - - const variations = variationList(uhepp) - const isVariationReady = noVariationUsed(uhepp) && (variations.length > 0) - - const rebin = uhepp_data.bins.rebin || uhepp_data.bins.edges return <> <div>{ Object.entries(uhepp.metadata.tags).map(([key, value]) => value == null ? @@ -129,7 +119,7 @@ const UheppHistUI = ({width, height, uhepp}) => { <span className="badge badge-pill badge-secondary">{value}</span> </span> ) }</div> - <UheppHist width={width} height={height} uhepp={uhepp_data_env} /> + <UheppHist width={width} height={height} uhepp={uhepp_derived} /> <ul className="nav nav-tabs" id="view-options" role="tablist"> <li className="nav-item"> @@ -181,7 +171,7 @@ const UheppHistUI = ({width, height, uhepp}) => { <div className="form-group"> <label htmlFor="rebin">Bin edges</label> <select multiple size={10} className="form-control" id="rebin" onChange={(e) => handleRebin(e)} - defaultValue={rebin}> + value={rebin}> {uhepp.bins.edges.map((v, i) => <option value={v} key={i}>{v}</option> )} @@ -190,7 +180,7 @@ const UheppHistUI = ({width, height, uhepp}) => { <div className="form-check"> <input className="form-check-input" type="checkbox" - checked={uhepp_data.bins.include_underflow == true} id="checkUnderflow" + checked={include_underflow == true} id="checkUnderflow" onChange={e => handleUnderflow(e)} /> <label className="form-check-label" htmlFor="checkUnderflow"> Include underflow events in first bin @@ -199,7 +189,7 @@ const UheppHistUI = ({width, height, uhepp}) => { <div className="form-check"> <input className="form-check-input" type="checkbox" - checked={uhepp_data.bins.include_overflow == true} id="checkOverflow" + checked={include_overflow == true} id="checkOverflow" onChange={e => handleOverflow(e)} /> <label className="form-check-label" htmlFor="checkOverflow"> Include overflow events in last bin @@ -211,10 +201,10 @@ const UheppHistUI = ({width, height, uhepp}) => { <div className="input-group"> <input type="number" className="form-control" id="densityWidth" onChange={e => handleDensityWidth(e)} - value={uhepp_data.bins.density_width || "0"} /> + value={density_width || "0"} /> { uhepp.variable.unit && <div className="input-group-append"> - <span className="input-group-text">{uhepp_data.variable.unit}</span> + <span className="input-group-text">{uhepp.variable.unit}</span> </div> } </div> @@ -230,7 +220,7 @@ const UheppHistUI = ({width, height, uhepp}) => { <form> <div className="form-group"> <label htmlFor="envelop">Add envelop of </label> - <select value={envName} className="form-control" id="envelop" onChange={(e) => handleEnvelop(e)}> + <select value={envName} className="form-control" id="envelop" onChange={(e) => onEnvChange(e)}> { [ <option value="NOMINAL" key="-1">Nominal</option>, ...variations.map((name, i) => <option value={name} key={i}>{name}</option>) @@ -240,8 +230,8 @@ const UheppHistUI = ({width, height, uhepp}) => { </div> <div className="form-group"> <label htmlFor="env-stack">for</label> - <select value={envId} className="form-control" id="env-stack" onChange={(e) => handleEnvStack(e)}> - { uhepp.stacks.map((stack, i) => <option value={i} key={i}>Stack {i} ({stack.content.length} items)</option>) } + <select value={envId} className="form-control" id="env-stack" onChange={(e) => onEnvStackChange(e)}> + { origStacks.map((stack, i) => <option value={i} key={i}>Stack {i} ({stack.content.length} items, {stack.type})</option>) } </select> </div> </form> @@ -257,4 +247,64 @@ const UheppHistUI = ({width, height, uhepp}) => { </div> </> } + +const UheppHistUI = ({width, height, uhepp}) => { + const [envId, setEnvId] = useState(0) + const [envName, setEnvName] = useState("NOMINAL") + + const reset = () => { + setEnvId(0) + setEnvName("NOMINAL") + } + const handleEnvelop = (e) => { + let variationName = e.target.value + setEnvName(variationName) + } + const handleEnvStack = (e) => { + let stackId = parseInt(e.target.value) + setEnvId(stackId) + } + + const variations = variationList(uhepp) + const isVariationReady = noVariationUsed(uhepp) && (variations.length > 0) + + const main_names = uhepp.stacks.map(stack => stack.content.map(item => item.yields)).flat() + const num_names = uhepp.ratio.map(item => item.numerator).flat() + const den_names = uhepp.ratio.map(item => item.denominator).flat() + const all_names = [...main_names, ...num_names, ...den_names] + + const filter_var = (var_updown) => objfilter(var_updown, (value, key) => ((all_names.indexOf(key) != -1) || key.indexOf(envName) != -1)) + const pruned = Object.assign({}, uhepp, + {"yields": objmap(uhepp.yields, y => Object.assign({}, y, { + "var_up": filter_var(y.var_up || {}), + "var_down": filter_var(y.var_down || {}), + }))} + ) + + const pruned_env = envName == "NOMINAL" ? pruned : Object.assign({}, pruned, + {stacks: [ + ...pruned.stacks, + ...makeVariationStacks(pruned, envId, envName, "up"), + ...makeVariationStacks(pruned, envId, envName, "down"), + ], + ratio: [ + ...makeVariationRatio(pruned, envId, envName, "up"), + ...makeVariationRatio(pruned, envId, envName, "down"), + ...pruned.ratio, + ]}, + ) + + return <UheppHistUIWithSyst + width={width} + height={height} + uhepp={pruned_env} + onEnvChange={e => handleEnvelop(e)} + onEnvStackChange={e => handleEnvStack(e)} + onReset={() => reset()} + envName={envName} + envId={envId} + origStacks={pruned.stacks} + isVariationReady={isVariationReady} + variations={variations} /> +} export default UheppHistUI; diff --git a/uhepp-js/src/helpers/uhepp.js b/uhepp-js/src/helpers/uhepp.js index 1bd6590..f293e0d 100644 --- a/uhepp-js/src/helpers/uhepp.js +++ b/uhepp-js/src/helpers/uhepp.js @@ -165,7 +165,7 @@ export const rebin = ( return result.map(x => post(x)) } -const fromEntires = (entries) => { +export const fromEntires = (entries) => { let result = {} entries.forEach(([key, value]) => { result[key] = value @@ -174,6 +174,7 @@ const fromEntires = (entries) => { } export const objmap = (obj, map) => fromEntires(Object.entries(obj).map(([key, value]) => [key, map(value, key)])) +export const objfilter = (obj, filter) => fromEntires(Object.entries(obj).filter(([key, value]) => filter(value, key))) /** * Processes the yield objects and returns a new version @@ -202,10 +203,10 @@ export const preprocessData = ({ "stat": yield_obj.stat ? rebin(yield_obj.stat, old_edges, eff_edges, (x) => x*x, (x)=>Math.sqrt(x)) : null, "syst": yield_obj.syst ? rebin(yield_obj.syst, old_edges, eff_edges, (x) => x*x, (x)=>Math.sqrt(x)) : null, "var_up": yield_obj.var_up ? objmap(yield_obj.var_up, - (value) => rebin(value, old_edges, eff_edges, (x) => x*x, (x)=>Math.sqrt(x)) + (value) => rebin(value, old_edges, eff_edges) ) : null, "var_down": yield_obj.var_down ? objmap(yield_obj.var_down, - (value) => rebin(value, old_edges, eff_edges, (x) => x*x, (x)=>Math.sqrt(x)) + (value) => rebin(value, old_edges, eff_edges) ) : null, } if (include_underflow) { -- GitLab