Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Includes an (approximate) EDFilter and a script to create JSON files according to the content of the run registry.
- Loading branch information
1 parent
ffc82cb
commit 5524b9a
Showing
3 changed files
with
241 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 122 additions & 0 deletions
122
Alignment/CommonAlignment/plugins/MagneticFieldFilter.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// -*- C++ -*- | ||
// | ||
// Package: Alignment/CommonAlignment | ||
// Class: MagneticFieldFilter | ||
// | ||
/**\class MagneticFieldFilter MagneticFieldFilter.cc Alignment/CommonAlignment/plugins/MagneticFieldFilter.cc | ||
Description: Plugin to filter events based on the magnetic field value | ||
Implementation: | ||
Takes the magnet current from the RunInfoRcd and translates it into a | ||
magnetic field value using the parameterization given here: | ||
https://hypernews.cern.ch/HyperNews/CMS/get/magnetic-field/63/1/1/1.html | ||
Agrees within an accuracy of ~20 mT with results of: | ||
https://cmswbm.web.cern.ch/cmswbm/cmsdb/servlet/RunSummary | ||
*/ | ||
// | ||
// Original Author: Gregor Mittag | ||
// Created: Wed, 25 Nov 2015 12:59:02 GMT | ||
// | ||
// | ||
|
||
|
||
// user include files | ||
#include "FWCore/Framework/interface/Frameworkfwd.h" | ||
#include "FWCore/Framework/interface/MakerMacros.h" | ||
#include "FWCore/Framework/interface/EventSetup.h" | ||
#include "FWCore/Framework/interface/ESHandle.h" | ||
#include "FWCore/ParameterSet/interface/ParameterSet.h" | ||
#include "CondFormats/RunInfo/interface/RunInfo.h" | ||
#include "CondFormats/DataRecord/interface/RunSummaryRcd.h" | ||
|
||
// | ||
// class declaration | ||
// | ||
|
||
class MagneticFieldFilter : public edm::stream::EDFilter<> { | ||
public: | ||
explicit MagneticFieldFilter(const edm::ParameterSet&); | ||
~MagneticFieldFilter() = default; | ||
|
||
static void fillDescriptions(edm::ConfigurationDescriptions&); | ||
|
||
private: | ||
virtual bool filter(edm::Event&, const edm::EventSetup&) override; | ||
virtual void beginRun(const edm::Run&, const edm::EventSetup&) override; | ||
|
||
/// convert Ampere (A) to Tesla (T) | ||
float currentToField(const float& current) const; | ||
|
||
// ----------member data --------------------------- | ||
/// see: https://hypernews.cern.ch/HyperNews/CMS/get/magnetic-field/63/1/1/1.html | ||
static constexpr float linearCoeffCurrentToField_ = 2.084287e-04; | ||
/// see: https://hypernews.cern.ch/HyperNews/CMS/get/magnetic-field/63/1/1/1.html | ||
static constexpr float constantTermCurrentToField_ = 1.704418e-02; | ||
|
||
const int magneticField_; /// magnetic field that is filtered | ||
int magneticFieldCurrentRun_; /// magnetic field estimate of the current run | ||
}; | ||
|
||
// | ||
// static data member definitions | ||
// | ||
constexpr float MagneticFieldFilter::linearCoeffCurrentToField_; | ||
constexpr float MagneticFieldFilter::constantTermCurrentToField_; | ||
|
||
|
||
// | ||
// constructor | ||
// | ||
MagneticFieldFilter::MagneticFieldFilter(const edm::ParameterSet& iConfig) : | ||
magneticField_(iConfig.getUntrackedParameter<int>("magneticField")), | ||
magneticFieldCurrentRun_(-10000) { | ||
} | ||
|
||
|
||
// | ||
// member functions | ||
// | ||
|
||
// ------------ method called on each new Event ------------ | ||
bool | ||
MagneticFieldFilter::filter(edm::Event&, const edm::EventSetup&) { | ||
return magneticField_ == magneticFieldCurrentRun_; | ||
} | ||
|
||
// ------------ method called when starting to processes a run ------------ | ||
|
||
void | ||
MagneticFieldFilter::beginRun(const edm::Run&, const edm::EventSetup& iSetup) { | ||
edm::ESHandle<RunInfo> sum; | ||
iSetup.get<RunInfoRcd>().get(sum); | ||
auto summary = sum.product(); | ||
// convert from Tesla to kGauss (multiply with 10) and | ||
// round off to whole kGauss (add 0.5 and cast to int) as is done in | ||
// 'MagneticField::computeNominalValue()': | ||
magneticFieldCurrentRun_ = | ||
static_cast<int>(currentToField(summary->m_avg_current)*10.0 + 0.5); | ||
} | ||
|
||
|
||
float | ||
MagneticFieldFilter::currentToField(const float& current) const { | ||
return linearCoeffCurrentToField_ * current + constantTermCurrentToField_; | ||
} | ||
|
||
|
||
// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ | ||
void | ||
MagneticFieldFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { | ||
edm::ParameterSetDescription desc; | ||
desc.setComment("Filters events with a magnetic field of 'magneticField'."); | ||
desc.addUntracked<int>("magneticField", 38) | ||
->setComment("In units of kGauss (= 0.1 Tesla)."); | ||
descriptions.add("magneticFieldFilter", desc); | ||
} | ||
|
||
//define this as a plug-in | ||
DEFINE_FWK_MODULE(MagneticFieldFilter); |
118 changes: 118 additions & 0 deletions
118
Alignment/CommonAlignment/scripts/magneticFieldFilterJSON.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
#!/usr/bin/env python | ||
|
||
import os | ||
import sys | ||
|
||
if not os.environ.has_key("CMSSW_BASE"): | ||
print "You need to source the CMSSW environment first." | ||
sys.exit(1) | ||
|
||
required_version = (2,7) | ||
if sys.version_info < required_version: | ||
print "Your Python interpreter is too old. Need version 2.7 or higher." | ||
sys.exit(1) | ||
|
||
import argparse | ||
|
||
import HLTrigger.Tools.rrapi as rrapi | ||
from FWCore.PythonUtilities.LumiList import LumiList | ||
|
||
|
||
def main(argv = None): | ||
"""Main routine of the script. | ||
Arguments: | ||
- `argv`: arguments passed to the main routine | ||
""" | ||
|
||
if argv == None: | ||
argv = sys.argv[1:] | ||
|
||
parser = argparse.ArgumentParser( | ||
description="Create JSON selection for a given magnetic field.") | ||
parser.add_argument("-i", "--input", dest="input", metavar="JSON", | ||
type=str, help="input JSON file") | ||
parser.add_argument("-o", "--output", dest="output", metavar="JSON", | ||
type=str, help="output JSON file") | ||
parser.add_argument("--min", dest="min", metavar="RUN", type=int, | ||
help="first run to be considered in the selection") | ||
parser.add_argument("--max", dest="max", metavar="RUN", type=int, | ||
help="last run to be considered in the selection") | ||
parser.add_argument("--epsilon", dest="epsilon", metavar="TESLA", | ||
default=0.1, type=float, | ||
help="precision of the filter (default: %(default)s T)") | ||
parser.add_argument("--debug", dest="debug", action="store_true", | ||
help="show more verbose output") | ||
required = parser.add_argument_group("required arguments") | ||
required.add_argument("--b-field", dest="bfield", metavar="TESLA", | ||
required=True, type=float, | ||
help="magnetic field to filter") | ||
args = parser.parse_args(argv) | ||
|
||
|
||
try: | ||
if args.input == None and (args.min == None or args.max == None): | ||
msg = ("If no input JSON file ('--input') is provided, you have to " | ||
"explicitly provide the first ('--min') and last ('--max') " | ||
"run.") | ||
raise RuntimeError(msg) | ||
|
||
if args.min != None and args.max != None and args.min > args.max: | ||
msg = "First run ({min:d}) is after last run ({max:d})." | ||
msg = msg.format(**args.__dict__) | ||
raise RuntimeError(msg) | ||
|
||
if args.max != None and args.max <= 0: | ||
msg = "Last run must be greater than zero: max = {0:d} <= 0." | ||
msg = msg.format(args.max) | ||
raise RuntimeError(msg) | ||
except RuntimeError, e: | ||
if args.debug: raise | ||
print ">>>", os.path.splitext(os.path.basename(__file__))[0]+":", str(e) | ||
sys.exit(1) | ||
|
||
|
||
lumi_list = None if not args.input else LumiList(filename = args.input) | ||
input_runs = None if not lumi_list else [int(r) for r in lumi_list.getRuns()] | ||
|
||
# Run registry API: https://twiki.cern.ch/twiki/bin/viewauth/CMS/DqmRrApi | ||
URL = "http://runregistry.web.cern.ch/runregistry/" | ||
api = rrapi.RRApi(URL, debug = args.debug) | ||
|
||
if api.app != "user": return | ||
|
||
column_list = ("number",) | ||
min_run = args.min if args.min != None else input_runs[0] | ||
max_run = args.max if args.max != None else input_runs[-1] | ||
bfield_min = args.bfield - args.epsilon | ||
bfield_max = args.bfield + args.epsilon | ||
constraints = { | ||
"datasetExists": "= true", | ||
"number": ">= {0:d} and <= {1:d}".format(min_run, max_run), | ||
"bfield": "> {0:f} and < {1:f}".format(bfield_min, bfield_max) | ||
} | ||
|
||
run_list = [item["number"] for item in | ||
api.data(workspace = "GLOBAL", table = "runsummary", | ||
template = "json", columns = column_list, | ||
filter = constraints)] | ||
|
||
if lumi_list != None: | ||
runs_to_remove = [] | ||
for run in input_runs: | ||
if run not in run_list: runs_to_remove.append(run) | ||
lumi_list.removeRuns(runs_to_remove) | ||
else: | ||
lumi_list = LumiList(runs = run_list) | ||
|
||
if args.output != None: | ||
lumi_list.writeJSON(args.output) | ||
with open(args.output+".args", "w") as f: | ||
f.write(" ".join(argv)+"\n") | ||
else: | ||
print lumi_list | ||
|
||
|
||
|
||
if __name__ == "__main__": | ||
main() |