├── data └── README ├── tests └── README ├── README.md ├── config.mk ├── setup_env64.sh ├── configure.sh ├── _parallelSlave.sh ├── include ├── PythiaPileUp.h ├── PileUp.h ├── ExtendableJet.h ├── JetAnalysis.h ├── Evgen.h └── Calorimeter.h ├── batchSubRotate.sh ├── _parallelMaster.sh ├── batchSubRerunLHE.sh ├── src ├── PileUp.cxx ├── PythiaPileUp.cxx ├── Evgen.cxx ├── Makefile ├── ExtendableJet.cxx ├── hepmcJets.cxx ├── Calorimeter.cxx ├── pythiaJets.cxx └── JetAnalysis.cxx ├── batchSubParallel.sh ├── mass_hists.py ├── batchSubHepMC.sh ├── batchSub.sh ├── setup_env.sh ├── MakeScatterPlot.py ├── InputCleaner.py ├── runMadgraph.py ├── text2bin.py ├── runHerwig.py ├── rotate_jets.py ├── simpleED.py └── pyrootmagic.py /data/README: -------------------------------------------------------------------------------- 1 | Directory for storing data -------------------------------------------------------------------------------- /tests/README: -------------------------------------------------------------------------------- 1 | Directory for storing test output -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | JetImages 2 | ========= 3 | 4 | Package to Create and run discrimination with Jet-Images. Code used for http://arxiv.org/abs/1407.5675 5 | -------------------------------------------------------------------------------- /config.mk: -------------------------------------------------------------------------------- 1 | SHELL = /bin/sh 2 | LHAPDFVERSION = 5.7.0 3 | LHAPDFLOCATION = /afs/cern.ch/sw/lcg/external/MCGenerators/lhapdf/5.7.0/x86_64-slc5-gcc43-opt/lib/archive 4 | LHAPDFLIBNAME = -lLHAPDF 5 | FASTJETLOCATION = /u/eb/joshgc/mynfs/FastJet/fastjet-install/ 6 | -------------------------------------------------------------------------------- /setup_env64.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | setup_g64python() { 4 | export PYTHONHOME=/afs/slac/g/glast/ground/GLAST_EXT/redhat5-x86_64-64bit-gcc41/python/2.7.2 5 | export PATH=$PYTHONHOME/bin:$PATH 6 | } 7 | 8 | setup_64sklearn() { 9 | export PYTHONPATH=/u/eb/joshgc/mynfs/scikit-learn/install_64/lib/python2.7/site-packages:$PYTHONPATH 10 | setup_g64python 11 | } 12 | 13 | setup_csjets() { 14 | setup_64sklearn 15 | } 16 | 17 | setup_csjets 18 | -------------------------------------------------------------------------------- /configure.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "You must source this script. Do not ./thisScript" 4 | export PYTHIA8LOCATION=/afs/slac/g/atlas/c/sw/lcg/external/MCGenerators/pythia8/150/i686-slc5-gcc43-opt/ 5 | export PYTHIA8DATA=${PYTHIA8LOCATION}xmldoc/ 6 | export BOOSTINCDIR=/usr/include 7 | export BOOSTLIBLOCATION=/usr/lib 8 | 9 | export PYTHONPATH=/u/eb/joshgc/mynfs/scikit-learn/install/lib/python2.7/site-packages:$PYTHONPATH 10 | export PYTHONHOME=/afs/slac/g/glast/ground/GLAST_EXT/redhat5-i686-32bit-gcc41/python/2.7.2 11 | export PATH=$PYTHONHOME/bin:$PATH 12 | -------------------------------------------------------------------------------- /_parallelSlave.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | uname -a 4 | 5 | export HomeDir=${1} 6 | shift 7 | export Cmd=${1} 8 | shift 9 | export Args=$* 10 | 11 | echo "HomeDir: $HomeDir" 12 | echo "Cmd : $Cmd" 13 | echo "Args : $Args" 14 | 15 | ID=`uuidgen` 16 | echo $HOSTNAME} ${PWD} 17 | 18 | [[ -e /tmp ]] && WorkDir=/tmp/${USER}/${ID} 19 | [[ -e /scratch ]] && WorkDir=/scratch/${USER}/${ID} 20 | 21 | cd ${HomeDir} 22 | . setup_env.sh 23 | 24 | mkdir -p ${WorkDir} 25 | cd ${WorkDir} 26 | ${Cmd} ${Args} 27 | cd - 28 | rm -rf ${WorkDir} 29 | 30 | echo "${ID} Done" 31 | -------------------------------------------------------------------------------- /include/PythiaPileUp.h: -------------------------------------------------------------------------------- 1 | #ifndef PYTHIAPILEUP_H 2 | #define PYTHIAPILEUP_H 3 | 4 | #include 5 | #include "Pythia.h" 6 | #include "PileUp.h" 7 | #include "Calorimeter.h" 8 | 9 | 10 | class PythiaPileUpGenerator : public PileUpGenerator{ 11 | 12 | private: 13 | void init(); 14 | 15 | public: 16 | Pythia8::Pythia pythia; 17 | 18 | PythiaPileUpGenerator(double averageIntPerCrossing, 19 | Calorimeter& refCalo, 20 | int randomSeed); 21 | virtual Calorimeter next(int exactIntPerCrossing); 22 | virtual vector next_vector(int exactIntPerCrossing); 23 | }; 24 | #endif 25 | -------------------------------------------------------------------------------- /include/PileUp.h: -------------------------------------------------------------------------------- 1 | #ifndef PILEUP_H 2 | #define PILEUP_H 3 | 4 | #define _USE_MATH_DEFINES 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "Calorimeter.h" 13 | 14 | class PileUpGenerator { 15 | 16 | protected: 17 | double m_mu; 18 | double m_max_for_poisson; 19 | int m_rSeed; 20 | int m_poissonSeed; 21 | Calorimeter m_refCalo; 22 | 23 | virtual void init(); 24 | int rand_int(int low, int high); 25 | double rand_range(double low, double high); 26 | 27 | //Will begin to break for mean > 10^9 28 | //Safe all the way down to and including mean =0 29 | unsigned int poisson_sample(double mean); 30 | double poisson(unsigned int nn, double mean); 31 | 32 | public: 33 | PileUpGenerator(double averageIntPerCrossing, 34 | Calorimeter& refCalo, 35 | int randomSeed); 36 | ~PileUpGenerator(){} 37 | 38 | double mu() const {return m_mu;} 39 | virtual Calorimeter next(int exactIntPerCrossing=-1) = 0; 40 | virtual vector next_vector(int exactIntPerCrossing=-1) = 0; 41 | }; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /batchSubRotate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Begin at `date`" 4 | 5 | [ "$USER" == "estrauss" ] && WorkDir=${PWD} && InputDir=/u/at/estrauss/afs/WTagger/logs_bhadron && OutputDir=/u/at/estrauss/afs/WTagger/npy_madgraph_bhadron 6 | 7 | SubFileLoc=`pwd`/_batchRotate.sh 8 | 9 | echo ' 10 | #!/bin/bash 11 | 12 | INDEX=`echo $LSB_BATCH_JID | sed -e "s/^[0-9]*//; s/\[//; s/\]//"` 13 | BASENAME=$2 14 | OUTPUT=$3/`basename ${BASENAME}` 15 | 16 | echo "Index: $INDEX" 17 | echo "Basename: $BASENAME" 18 | echo "Output: $OUTPUT" 19 | 20 | cd $1 21 | 22 | if [ `ls ${BASENAME}_${INDEX}.* | wc -l` == 0]; then 23 | echo "No such file ${BASENAME}_${INDEX}.*" 24 | exit 0 25 | fi 26 | 27 | . setup_env.sh 28 | T=$(($RANDOM%600)) 29 | echo "Sleep for $T seconds" 30 | sleep $T 31 | echo python rotate_jets.py -n -1 -i ${BASENAME}_${INDEX}.* -o ${OUTPUT}_${INDEX}.npy 32 | python rotate_jets.py -n -1 -i ${BASENAME}_${INDEX}.* -o ${OUTPUT}_${INDEX}.npy 33 | ' > $SubFileLoc 34 | chmod u+x $SubFileLoc 35 | 36 | mkdir -p ${OutputDir} 37 | 38 | SAMPLES=`ls $InputDir/* | sed -e 's/_[0-9]*.\(log\|tgz\)//' | sort -u` 39 | 40 | for SAMPLE in $SAMPLES; do 41 | echo `bjobs | wc -l` 42 | while [[ `bjobs|wc -l` -ge 120 ]]; do 43 | echo "More than 120 jobs on the queues, waiting for some to clear" 44 | sleep 300 45 | done 46 | echo "Submit $SAMPLE" 47 | N=`ls ${SAMPLE}* | wc -l` 48 | bsub -q medium -J `basename ${SAMPLE}`[1-$N] -R rhel50 $SubFileLoc $WorkDir $SAMPLE $OutputDir 49 | sleep 2 50 | done 51 | 52 | echo "Done at `date`" 53 | -------------------------------------------------------------------------------- /_parallelMaster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | setup_job() { 4 | echo "Setting up job" 5 | cd ${SourceDir} 6 | . setup_env.sh 7 | 8 | ID=`uuidgen` 9 | [[ -e /tmp ]] && WorkDir=/tmp/${USER}/${ID} 10 | [[ -e /scratch ]] && WorkDir=/scratch/${USER}/${ID} 11 | 12 | echo "WorkDir = ${WorkDir}" 13 | 14 | mkdir -p ${WorkDir} 15 | cd ${WorkDir} 16 | } 17 | 18 | cleanup_job() { 19 | echo "Cleaning up job" 20 | cd ${WorkDir} 21 | echo "================" 22 | echo "ls $PWD" 23 | ls 24 | echo "================" 25 | find . -name '*.gen.log' -print0 | xargs -0 -I % sh -c 'echo == % ==; cat %' > ${LocalLogFile}.log 26 | tar -czvf ${LocalLogFile}.tgz ${LocalLogFile}.log 27 | echo mv ${LocalLogFile}.tgz ${LogFile}.tgz 28 | mv ${LocalLogFile}.tgz ${LogFile}.tgz 29 | cd .. 30 | rm -rf ${WorkDir} 31 | } 32 | 33 | run_subjobs() { 34 | cd 35 | PIDS="" 36 | for HOST in $LSB_HOSTS; do 37 | ID=`uuidgen` 38 | (lsrun -m "$HOST" ${SourceDir}/_parallelSlave.sh ${SourceDir} ${Cmd} ${Args}) &> ${WorkDir}/${ID}.gen.log & 39 | PIDS="$PIDS $!" 40 | done 41 | cd - 42 | } 43 | 44 | mill_around() { 45 | echo "Waiting for subjobs to end with PID: ${PIDS}" 46 | Running=1 47 | while [[ ${Running} -eq 1 ]]; do 48 | sleep $(($RANDOM%300)) 49 | Running=0 50 | for PID in $PIDS; do 51 | kill -0 ${PID} &> /dev/null && Running=1 52 | done 53 | done 54 | } 55 | 56 | 57 | LogFile=${1} 58 | shift 59 | SourceDir=${1} 60 | shift 61 | NSubJobs=${1} 62 | shift 63 | Cmd=${SourceDir}/${1} 64 | shift 65 | Args=$* 66 | 67 | LogFile="${LogFile}_`echo $LSB_BATCH_JID | sed -e 's/\[/_/; s/\]//'`" 68 | LocalLogFile=`basename ${LogFile}` 69 | 70 | echo "Begin at `date`" 71 | echo SourceDir = $SourceDir 72 | echo LogFile = ${LogFile} 73 | echo Cmd = $Cmd 74 | echo Args = $Args 75 | 76 | echo "Subjob hosts: $LSB_HOSTS" 77 | setup_job 78 | run_subjobs ${NSubJobs} 79 | 80 | trap cleanup_job SIGHUP SIGINT SIGTERM 81 | 82 | mill_around 83 | cleanup_job 84 | 85 | echo "Let's blow this popsicle stand" 86 | echo "End at `date`" 87 | -------------------------------------------------------------------------------- /batchSubRerunLHE.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Begin at `date`" 4 | 5 | [ "$USER" == "estrauss" ] && HomeDir=${PWD} && InputDir=/u/at/estrauss/atlint02/logs_madgraph/ && OutputDir=/u/at/estrauss/atlint02/logs_madgraph_v2_fixed/ 6 | 7 | SubFileLoc=`pwd`/_batchRerunLHE.sh 8 | 9 | echo ' 10 | #!/bin/bash 11 | 12 | INDEX=`echo $LSB_BATCH_JID | sed -e "s/^[0-9]*//; s/\[//; s/\]//"` 13 | 14 | BASENAME=$2 15 | OUTPUT=$3/`basename ${BASENAME}` 16 | 17 | ID=`uuidgen` 18 | [[ -e /tmp ]] && WORKDIR=/tmp/${USER}/${ID} 19 | [[ -e /scratch ]] && WORKDIR=/scratch/${USER}/${ID} 20 | 21 | echo "Index: $INDEX" 22 | echo "Basename: $BASENAME" 23 | echo "Output: $OUTPUT" 24 | echo "WorkDir: $WORKDIR" 25 | 26 | cd $1 27 | 28 | if [ `ls ${BASENAME}_${INDEX}.* | wc -l` == 0 ]; then 29 | echo "No such file ${BASENAME}_${INDEX}.*" 30 | exit 0 31 | fi 32 | 33 | . setup_env.sh 34 | T=$(($RANDOM%600)) 35 | echo "Sleep for $T seconds" 36 | sleep $T 37 | 38 | mkdir -p ${WORKDIR} 39 | if [[ "$?" != "0" ]]; then 40 | echo "Could not create WorkDir" 41 | exit 1 42 | fi 43 | 44 | cd ${WORKDIR} 45 | 46 | LOGNAME=`tar -xzvf ${BASENAME}_${INDEX}.*` 47 | awk "/Start LHE File/{x=\"F\"++i;next}{print > \"${LOGNAME}_split\"x;}" ${LOGNAME} 48 | 49 | for FILE in `ls ${LOGNAME}_splitF*`; do 50 | echo "Process ${FILE}" 51 | echo "@@ Start LHE File" >> regen.log 52 | awk "//{f=1;}f&&/End LHE File/{exit}f" ${FILE} >> regen.log 53 | echo "@@ END LHE File" >> regen.log 54 | `grep "Called as" ${FILE} | sed -e "s/Called as: //; s/LHEFile=.*lhe/LHEFile=${FILE}/"` >> regen.log 55 | done 56 | 57 | tar -czvf ${OUTPUT}_${INDEX}.tgz regen.log 58 | cd $1 59 | rm -rf ${WORKDIR} 60 | 61 | ' > $SubFileLoc 62 | chmod u+x $SubFileLoc 63 | 64 | mkdir -p ${OutputDir} 65 | 66 | SAMPLES=`ls $InputDir/* | sed -e 's/_[0-9]*.\(log\|tgz\)//' | sort -u` 67 | 68 | for SAMPLE in $SAMPLES; do 69 | while [[ `bjobs|wc -l` -ge 100 ]]; do 70 | echo "More than 100 jobs on the queues, waiting for some to clear" 71 | sleep 300 72 | done 73 | echo "Submit $SAMPLE" 74 | N=`ls ${SAMPLE}* | wc -l` 75 | bsub -q long -J `basename ${SAMPLE}`[1-$N] -R rhel50 $SubFileLoc $HomeDir $SAMPLE $OutputDir 76 | sleep 30 77 | done 78 | 79 | echo "Done at `date`" 80 | -------------------------------------------------------------------------------- /src/PileUp.cxx: -------------------------------------------------------------------------------- 1 | #define _USE_MATH_DEFINES 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "Calorimeter.h" 10 | #include "PileUp.h" 11 | 12 | void 13 | PileUpGenerator::init(){ 14 | m_refCalo.reset(); 15 | 16 | m_max_for_poisson = poisson(m_mu, (unsigned int) m_mu); 17 | m_poissonSeed = m_rSeed; 18 | srand( m_poissonSeed ); 19 | } 20 | 21 | int 22 | PileUpGenerator::rand_int(int low, int high){ 23 | int rr = rand(); 24 | srand(rr); 25 | 26 | return (int)((rr/(float)RAND_MAX) * abs(high - low)) + min(high, low); 27 | } 28 | 29 | double 30 | PileUpGenerator::rand_range(double low, double high){ 31 | int rr = rand(); 32 | srand(rr); 33 | 34 | return (rr/(float)RAND_MAX) * abs(high - low) + min(high, low); 35 | } 36 | 37 | //Will begin to break for mean > 10^9 38 | //Safe all the way down to and including mean =0 39 | unsigned int 40 | PileUpGenerator::poisson_sample(double mean){ 41 | const unsigned int max_n = max((int)(6*mean), 2); 42 | 43 | unsigned int nn; 44 | double yy; 45 | 46 | //disallow possibility of two or more 47 | if (mean < 1e-3) { 48 | if (rand_range(0,1) < mean) return 1; 49 | else return 0; 50 | } 51 | 52 | //Average iteations through loop: 53 | //Means >~ 10: 2.4*sqrt(mean) 54 | //Means << 1 : 0.8/sqrt(mean) 55 | for(unsigned int ii=0; ii<=1000*1000; ++ii){ 56 | nn = rand_int(0, max_n);//(unsigned int)(rand() * max_n); 57 | yy = rand_range(0, m_max_for_poisson);//rand() * m_max_for_poisson; 58 | 59 | if (yy > poisson(nn, mean)) continue; 60 | 61 | return nn; 62 | } 63 | 64 | return 0; 65 | } 66 | 67 | double 68 | PileUpGenerator::poisson(unsigned int nn, double mean){ 69 | double acc = 1; 70 | for(unsigned int ii=1; ii<=nn; ++ii) acc *= (mean/ii); 71 | 72 | return exp(-1*mean)*acc; 73 | } 74 | 75 | PileUpGenerator::PileUpGenerator(double averageIntPerCrossing, 76 | Calorimeter& refCalo, 77 | int randomSeed){ 78 | m_mu = averageIntPerCrossing; 79 | m_refCalo = refCalo; 80 | m_rSeed = randomSeed; 81 | init(); 82 | } 83 | -------------------------------------------------------------------------------- /batchSubParallel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Begin at `date`" 4 | 5 | [ "$USER" == "joshgc" ] && WorkDir=/afs/slac.stanford.edu/u/eb/joshgc/trunk/CSJets && LogDir=/u/eb/joshgc/mynfs/CSJets/logs 6 | [ "$USER" == "estrauss" ] && WorkDir=${PWD} && LogDir=/u/at/estrauss/afs/WTagger/logs_subjobs/ 7 | 8 | SubFileLoc=${WorkDir}/_parallelMaster.sh 9 | DateSuffix=`date +%s` 10 | 11 | rad=1.2 12 | gen="p" 13 | [[ "$gen" == "p" ]] && prog="./pythiaJets.exe" 14 | [[ "$gen" == "h" ]] && prog="./runHerwig.py" 15 | 16 | 17 | for metype in w v g; do 18 | for trim in 0 1; do 19 | for mu in 0 30; do 20 | Queue=long 21 | nevents=50000 22 | nsubjobs=10 23 | njobs=15 24 | [[ "$metype" == "g" ]] && nevents=$(($nevents * 50)) 25 | [[ "$metype" == "v" ]] && nevents=$(($nevents * 100)) 26 | [[ "$metype" == "w" ]] && nevents=$(($nevents * 20)) 27 | [[ "$mu" == "30" ]] && njobs=$(($njobs*4)) 28 | nevents=$(($nevents / ($njobs*$nsubjobs) )) 29 | for pt_start in 200 500; do 30 | LogPrefix=${LogDir}/bsub_${DateSuffix}_${gen}_${metype}_${rad}_${pt_start}_${mu}_T${trim} 31 | mkdir -p `dirname $LogPrefix` 32 | echo 33 | echo "Submitting $njobs jobs each with $nsubjobs subjobs running $nevents events to $Queue with prefix $LogPrefix" 34 | echo $LogPrefix 35 | bsub -J "${LogPrefix}[1-${njobs}]" -R "rhel50" -n ${nsubjobs} -q ${Queue} $SubFileLoc \ 36 | ${LogPrefix} \ 37 | ${WorkDir} \ 38 | ${nsubjobs} \ 39 | ${prog} --nevents ${nevents} \ 40 | --savemaxnjets 1 \ 41 | --metype $metype \ 42 | --mu $mu \ 43 | --rad $rad \ 44 | --trimjet ${trim} \ 45 | --wtagger \ 46 | --lepcharge 1 \ 47 | --meminpt $((pt_start-50)) \ 48 | --memaxpt $((pt_start+100)) \ 49 | --jetminpt $pt_start \ 50 | --jetmaxpt $((pt_start+50)) \ 51 | --jetminm 55 \ 52 | --jetmaxm 105 53 | 54 | done 55 | done 56 | done 57 | done 58 | 59 | echo "End at `date`" 60 | 61 | -------------------------------------------------------------------------------- /mass_hists.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | 4 | 5 | def draw(nameAndLists, limits, fname): 6 | fig = plt.figure() 7 | ax = fig.add_subplot(111) 8 | for name, li in nameAndLists: 9 | if '30' in name: 10 | if 'Untrim' in name: 11 | cc = 'b00000' 12 | else: 13 | cc = 'ff7272' 14 | else: 15 | if 'Untrim' in name: 16 | cc = '0000b0' 17 | else: 18 | cc = '7272ff' 19 | cc = '#'+cc 20 | hh, edges = np.histogram(li, limits[0], limits[1:3]) 21 | xs = (edges[0:-1] + edges[1:])/2.0 22 | #ax.plot(xs, hh, 'o', label=name) 23 | ax.errorbar(xs, hh, yerr=np.sqrt(hh), markeredgecolor=cc,markerfacecolor=cc,ecolor=cc, fmt='o', label=name) 24 | 25 | 26 | ax.set_xlabel("Jet Mass (GeV)") 27 | ax.set_ylabel("#Entries per %.1f GeV" % ((limits[2] - limits[1]+0.0)/limits[0])) 28 | ax.set_ylim(0, 1.2*ax.get_ylim()[1]) 29 | plt.legend() 30 | plt.savefig(fname) 31 | #plt.show() 32 | 33 | 34 | 35 | if __name__ == '__main__': 36 | inpath='/u/eb/joshgc/mynfs/CSJets/' 37 | nameAndLocations = [('Trimmed t mu=0' , 't_0_mass_trim_1.mass' ), 38 | ('Trimmed t mu=30' , 't_30_mass_trim_1.mass'), 39 | ('Untrimmed t mu=0' , 't_0_mass_trim_0.mass'), 40 | ('Untrimmed t mu=30', 't_30_mass_trim_0.mass'), 41 | ] 42 | outname = 't_trimming.png' 43 | limits = (40,50,250) 44 | 45 | #nameAndLocations = [('Trimmed W mu=0' , 'w_0_mass_trim_1.mass' ), 46 | # ('Trimmed W mu=30' , 'w_30_mass_trim_1.mass'), 47 | # ('Untrimmed W mu=0' , 'w_0_mass_trim_0.mass'), 48 | # ('Untrimmed W mu=30', 'w_30_mass_trim_0.mass'), 49 | # ] 50 | 51 | #outname = 'w_trimming.png' 52 | #limits = (50, 0, 150) 53 | 54 | nameAndLocations = [('Trimmed g mu=0' , 'g_0_mass_trim_1.mass' ), 55 | ('Trimmed g mu=30' , 'g_30_mass_trim_1.mass'), 56 | ('Untrimmed g mu=0' , 'g_0_mass_trim_0.mass'), 57 | ('Untrimmed g mu=30', 'g_30_mass_trim_0.mass'), 58 | ] 59 | 60 | outname = 'g_trimming.png' 61 | limits = (50, 0, 150) 62 | 63 | nameAndLists = [(name, list(float(xx) for xx in open(inpath+loc))) 64 | for name,loc in nameAndLocations] 65 | 66 | 67 | draw(nameAndLists, limits,outname) 68 | -------------------------------------------------------------------------------- /include/ExtendableJet.h: -------------------------------------------------------------------------------- 1 | #ifndef EXTENDABLEJET_H 2 | #define EXTENDABLEJET_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "fastjet/ClusterSequence.hh" 9 | 10 | #include "Calorimeter.h" 11 | 12 | using namespace std; 13 | using fastjet::PseudoJet; 14 | 15 | class ExtendableJet{ 16 | private: 17 | map properties; 18 | Calorimeter calo; 19 | vector m_pu_calos; 20 | double m_subjetRadius; 21 | double m_radius; 22 | unsigned int m_nSubjets; 23 | double m_dcut; 24 | 25 | std::set chargedIds; 26 | 27 | void init(PseudoJet &pJet, 28 | Calorimeter &filledCalo, 29 | vector &pu_calos, 30 | double radius, 31 | unsigned int nSubjets, 32 | double subjetRadius); 33 | 34 | public: 35 | PseudoJet jet; 36 | 37 | ExtendableJet(){} 38 | 39 | // ExtendableJet(PseudoJet &pJet, 40 | // Calorimeter &filledCalo, double radius){ 41 | // init(pJet, filledCalo, radius, 2, 0.2); 42 | // } 43 | 44 | ExtendableJet(PseudoJet &pJet, 45 | Calorimeter &filledCalo, 46 | vector &pu_calos, 47 | double radius, 48 | unsigned int nSubjets, 49 | double subjetRadius){ 50 | init(pJet, filledCalo, pu_calos, radius, nSubjets, subjetRadius); 51 | } 52 | 53 | double radius() const { return m_radius;} 54 | 55 | static bool 56 | compare(const PseudoJet& aa, const PseudoJet& bb){ return aa.pt() < bb.pt();} 57 | 58 | unsigned int getNTracks() const ; 59 | 60 | template 61 | void setProperty(string key, T value){ 62 | stringstream ss; 63 | ss << value; 64 | properties[key] = ss.str(); 65 | } 66 | 67 | void setProperty(map user_props){ 68 | map::iterator it; 69 | for(it=user_props.begin(); it != user_props.end(); ++it) 70 | properties[it->first] = it->second; 71 | } 72 | 73 | inline string toString() const {toString(1);} 74 | string toString(int level) const ; 75 | void operator<<(ostream& out) {out << toString();} 76 | double get_cos_theta(const vector &subjets) const; 77 | }; 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /batchSubHepMC.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | [ "$USER" == "joshgc" ] && WorkDir=/afs/slac.stanford.edu/u/eb/joshgc/trunk/CSJets && LogDir=/u/eb/joshgc/mynfs/CSJets/logs 4 | [ "$USER" == "estrauss" ] && WorkDir=${PWD} && LogDir=/u/at/estrauss/afs/WTagger/logs_herwig_v4 5 | 6 | SubFileLoc=`pwd`/_batchSingleSubHepMC.sh 7 | DateSuffix=`date +%s` 8 | 9 | echo '#!/bin/bash 10 | set -e 11 | echo WORKDIR to $1 12 | echo CMD is $2 13 | 14 | ID=`uuidgen` 15 | mkdir -p /scratch/${USER}/${ID} 16 | 17 | cd $1 18 | source setup_env.sh 19 | cd /scratch/${USER}/${ID} 20 | cmd=$1/$2 21 | 22 | shift 23 | shift 24 | echo Calling $cmd $* 25 | $cmd $* 26 | 27 | cd /scratch 28 | rm -rf /scratch/${USER}/${ID} 29 | ' > $SubFileLoc 30 | chmod u+x $SubFileLoc 31 | 32 | rad=1.2 33 | for metype in v w; do 34 | for mu in 0 ; do 35 | Queue=long 36 | nevents=50000 37 | njobs=20 38 | [ "$mu" == "30" ] && Queue=long && nevents=5000 && njobs=1000 39 | [ "$mu" == "0" ] && Queue=medium && nevents=10000 && njobs=40 40 | [ "$metype" == "v" ] && njobs=$((njobs*4)) 41 | for pt_start in 200 500; do 42 | LogPrefix=${LogDir}/bsub_${metype}_${pt_start}_${mu}_${rad}_${DateSuffix}_ 43 | mkdir -p `dirname $LogPrefix` 44 | echo 45 | echo "Submitting $njobs jobs each with $nevents events to $Queue" 46 | echo $LogPrefix 47 | for (( ii=1; ii<=$njobs; ii++ )) ; do 48 | echo $ii 49 | bsub -R rhel50 -q ${Queue} -o $LogPrefix${ii}.log $SubFileLoc \ 50 | ${WorkDir} \ 51 | ./runHerwig.py --nevents ${nevents} \ 52 | --seed ${ii} \ 53 | --savemaxnjets 1 \ 54 | --metype $metype \ 55 | --mu $mu \ 56 | --rad $rad \ 57 | --trimjet 1 \ 58 | --wtagger \ 59 | --lepcharge 1 \ 60 | --meminpt $((pt_start-50)) \ 61 | --memaxpt $((pt_start+100)) \ 62 | --jetminpt $pt_start \ 63 | --jetmaxpt $((pt_start+50)) \ 64 | --jetminm 60 \ 65 | --jetmaxm 100 66 | 67 | done 68 | done 69 | done 70 | done 71 | 72 | #files=(~/mynfs/CSJets/logs/bsub_*.log) 73 | # 74 | #for in_file in ${files[*]} ; do 75 | # out_file=${in_file%.*} 76 | # 77 | # echo $in_file $out_file 78 | # bsub -q long -o ${out_file}_rotate.log $SubFileLoc \ 79 | # /afs/slac.stanford.edu/u/eb/joshgc/trunk/CSJets \ 80 | # python rotate_jets.py -1 $in_file $out_file.npy 81 | # 82 | #done 83 | -------------------------------------------------------------------------------- /batchSub.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Begin at `date`" 4 | 5 | [ "$USER" == "joshgc" ] && WorkDir=/afs/slac.stanford.edu/u/eb/joshgc/trunk/CSJets && LogDir=/u/eb/joshgc/mynfs/CSJets/logs 6 | [ "$USER" == "estrauss" ] && WorkDir=${PWD} && LogDir=/u/at/estrauss/afs/WTagger/logs_17052013/ 7 | 8 | SubFileLoc=`pwd`/_batchSingleSub.sh 9 | DateSuffix=`date +%s` 10 | 11 | echo '#!/bin/bash 12 | echo CD to $1 13 | echo CMD is $2 14 | 15 | cd $1 16 | source setup_env.sh 17 | cmd=$2 18 | 19 | shift 20 | shift 21 | echo Calling $cmd $* 22 | $cmd $*' > $SubFileLoc 23 | chmod u+x $SubFileLoc 24 | 25 | rad=1.2 26 | gen="p" 27 | 28 | total_nevents=50000 29 | 30 | for metype in w v g; do 31 | for trim in 0 1; do 32 | for mu in 0 30; do 33 | Queue=long 34 | nevents=$((total_nevents * 10)) 35 | njobs=100 36 | #Correct number of events for approx efficiency of a 10 GeV mass window 37 | [[ "$metype" == "g" ]] && nevents=$((total_nevents * 50)) 38 | [[ "$metype" == "v" ]] && nevents=$((total_nevents * 100)) 39 | [[ "$metype" == "w" ]] && nevents=$((total_nevents * 20)) 40 | #mu = 30 jobs run longer 41 | [[ "$mu" == "30" ]] && njobs=$((njobs*5)) 42 | nevents=$((nevents/njobs + 1)) 43 | for pt_start in 200 500 ; do 44 | LogPrefix=${LogDir}/bsub_${DateSuffix}_${gen}_${metype}_${rad}_${pt_start}_${mu}_T${trim}_ID 45 | mkdir -p `dirname $LogPrefix` 46 | echo 47 | echo "Submitting $njobs jobs each with $nevents events to $Queue with prefix $LogPrefix" 48 | echo $LogPrefix 49 | bsub -R rhel50 -q ${Queue} -o "${LogPrefix}%I.out" -J "${LogPrefix}[1-${njobs}]" $SubFileLoc\ 50 | ${WorkDir} \ 51 | ./pythiaJets.exe --nevents ${nevents} \ 52 | --savemaxnjets 1 \ 53 | --metype $metype \ 54 | --mu $mu \ 55 | --rad $rad \ 56 | --trimjet ${trim} \ 57 | --wtagger \ 58 | --lepcharge 1 \ 59 | --meminpt $((pt_start-50)) \ 60 | --memaxpt $((pt_start+100)) \ 61 | --jetminpt $pt_start \ 62 | --jetmaxpt $((pt_start+50)) \ 63 | --jetminm 55 \ 64 | --jetmaxm 105 65 | 66 | done 67 | done 68 | done 69 | done 70 | 71 | echo "End at `date`" 72 | 73 | #files=(~/mynfs/CSJets/logs/bsub_*.log) 74 | # 75 | #for in_file in ${files[*]} ; do 76 | # out_file=${in_file%.*} 77 | # 78 | # echo $in_file $out_file 79 | # bsub -q long -o ${out_file}_rotate.log $SubFileLoc \ 80 | # /afs/slac.stanford.edu/u/eb/joshgc/trunk/CSJets \ 81 | # python rotate_jets.py -1 $in_file $out_file.npy 82 | # 83 | #done 84 | -------------------------------------------------------------------------------- /src/PythiaPileUp.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Pythia.h" 3 | 4 | #include "PileUp.h" 5 | #include "PythiaPileUp.h" 6 | #include "Calorimeter.h" 7 | 8 | 9 | void 10 | PythiaPileUpGenerator::init(){ 11 | 12 | cout << "INIT from PPU"<< endl; 13 | pythia.readString("HardQCD:all = off"); 14 | pythia.readString("SoftQCD:minBias = on"); 15 | pythia.readString("Random:setSeed = on"); 16 | pythia.readString("PhaseSpace:pTHatMin = .1"); 17 | 18 | std::stringstream ss; 19 | ss << "Random:seed = " << m_rSeed; 20 | pythia.readString(ss.str()); 21 | 22 | pythia.init(2212, 2212, 8000); 23 | } 24 | 25 | PythiaPileUpGenerator::PythiaPileUpGenerator( 26 | double averageIntPerCrossing, 27 | Calorimeter& refCalo, 28 | int randomSeed) 29 | : PileUpGenerator(averageIntPerCrossing, refCalo, randomSeed) 30 | { 31 | init();//child class init needs explicit calling 32 | } 33 | 34 | 35 | Calorimeter 36 | PythiaPileUpGenerator::next(int exactIntPerCrossing=-1){ 37 | const int usrInts = exactIntPerCrossing; 38 | const unsigned int nInts = usrInts > -1 ? usrInts : poisson_sample(m_mu); 39 | Pythia8::Particle pp; 40 | 41 | Calorimeter calo_fill = Calorimeter(m_refCalo); 42 | calo_fill.set_nInteractions(nInts); 43 | vector pjs; 44 | PseudoJet pj; 45 | for(unsigned int i_pu = 0; i_pu < nInts; ){ 46 | if (!pythia.next()) continue; 47 | 48 | for (int iPart = 0; iPart < pythia.event.size(); ++iPart) { 49 | pp = pythia.event[iPart]; 50 | if (pp.isFinal() && pp.isVisible()) { 51 | pj.reset_momentum(pp.px(), pp.py(), pp.pz(), pp.e()); 52 | pj.set_user_index(pp.id()); 53 | pjs.push_back(pj); 54 | } 55 | } 56 | //don't count events pythia crapped out on 57 | ++i_pu; 58 | } 59 | 60 | calo_fill.push(pjs); 61 | 62 | return calo_fill; 63 | } 64 | 65 | vector 66 | PythiaPileUpGenerator::next_vector(int exactIntPerCrossing=-1){ 67 | const int usrInts = exactIntPerCrossing; 68 | const unsigned int nInts = usrInts > -1 ? usrInts : poisson_sample(m_mu); 69 | Pythia8::Particle pp; 70 | 71 | vector ret_vec; 72 | vector pjs; 73 | PseudoJet pj; 74 | 75 | for(unsigned int i_pu = 0; i_pu < nInts; ){ 76 | if (!pythia.next()) continue; 77 | 78 | pjs.clear(); 79 | 80 | for (int iPart = 0; iPart < pythia.event.size(); ++iPart) { 81 | pp = pythia.event[iPart]; 82 | if (pp.isFinal() && pp.isVisible()) { 83 | pj.reset_momentum(pp.px(), pp.py(), pp.pz(), pp.e()); 84 | pj.set_user_index(pp.id()); 85 | pjs.push_back(pj); 86 | } 87 | } 88 | 89 | ret_vec.push_back(Calorimeter(m_refCalo)); 90 | ret_vec[i_pu].set_nInteractions(1); 91 | ret_vec[i_pu].push(pjs); 92 | 93 | //don't count events pythia crapped out on 94 | ++i_pu; 95 | } 96 | 97 | 98 | return ret_vec; 99 | } 100 | -------------------------------------------------------------------------------- /include/JetAnalysis.h: -------------------------------------------------------------------------------- 1 | #ifndef JETANALYSIS_H 2 | #define JETANALYSIS_H 3 | 4 | #include 5 | 6 | //physics things josh found 7 | #include "HepMC/GenEvent.h" 8 | 9 | //physics things josh installed 10 | #include "fastjet/ClusterSequence.hh" 11 | #include "fastjet/tools/Filter.hh" 12 | #include "fastjet/tools/MassDropTagger.hh" 13 | #include "Nsubjettiness/Nsubjettiness.hh" 14 | 15 | //physics things josh wrote 16 | #include "JetAnalysis.h" 17 | #include "Calorimeter.h" 18 | #include "PileUp.h" 19 | 20 | 21 | class Cuts{ 22 | public: 23 | Cuts() { clear(); } 24 | 25 | void add_cut(std::string name) { 26 | m_passed.push_back(0); 27 | m_name.push_back(name); 28 | } 29 | 30 | void passed(std::string cut_name = ""); 31 | 32 | void clear() { 33 | m_counter = 0; 34 | m_passed.clear(); 35 | m_name.clear(); 36 | } 37 | 38 | void begin() { m_counter = 0; } 39 | 40 | void print(); 41 | 42 | private: 43 | std::vector m_passed; 44 | std::vector m_name; 45 | int m_counter; 46 | }; 47 | 48 | class JetAnalysis{ 49 | 50 | private: 51 | std::vector selectGoodJets(fastjet::ClusterSequence &cs); 52 | inline bool inMassRange(double jetMass) const; 53 | 54 | 55 | private: 56 | int m_saveMaxNJets; 57 | int m_cellV; 58 | int m_trimJets; 59 | float m_jetMinPt; 60 | float m_jetMaxPt; 61 | float m_jetMinM; 62 | float m_jetMaxM; 63 | float m_jetRadius; 64 | int m_mu; 65 | int m_nB; 66 | bool m_doSmear; 67 | bool m_doWTagger; 68 | 69 | float m_minDR; 70 | float m_trimRadius; 71 | 72 | fastjet::MassDropTagger m_mdt; 73 | fastjet::JetDefinition m_primaryDef; 74 | fastjet::JetDefinition m_trimDef; 75 | fastjet::Selector m_selPtMin; 76 | fastjet::Selector m_selPtMax; 77 | fastjet::Selector m_basePtMin; 78 | fastjet::Selector m_selDR; 79 | fastjet::Selector m_selEta; 80 | std::map m_nSubCalcs; 81 | 82 | std::string m_desc; 83 | 84 | Calorimeter m_hs_calo; 85 | PileUpGenerator *m_pug; 86 | 87 | std::vector m_wtagEffs; 88 | 89 | void init(int saveMaxNJets, int trimJets, float jetMinPt, float jetMaxPt, float jetMinM, float jetMaxM, float jetRadius, int nB, int mu, int puSeed, bool doSmear, bool doWTagger, int cellV); 90 | double get_bdrs_mass(const PseudoJet &pj, bool require_two_bs) const; 91 | 92 | Cuts m_jetCuts; 93 | Cuts m_pclCuts; 94 | 95 | public: 96 | // probably also want algorithm 97 | JetAnalysis(int saveMaxNJets, int trimJets, float jetMinPt, float jetMaxPt, float jetMinM, float jetMaxM, float jetRadius, int nB, int mu, int puSeed, bool doSmear, bool doWTagger, int cellV) { 98 | init(saveMaxNJets, trimJets, jetMinPt, jetMaxPt, jetMinM, jetMaxM, jetRadius, nB, mu, puSeed, doSmear, doWTagger, cellV); 99 | } 100 | 101 | ~JetAnalysis(); 102 | 103 | inline static bool is_qhadron(int qid, int pid); 104 | static bool is_final_qhadron(int qid, HepMC::GenParticle *gp); 105 | static bool is_charged(int pdg_id); 106 | void analyze(HepMC::GenEvent* event, map props); 107 | HepMC::GenParticle* findBestParton(PseudoJet &jet, HepMC::GenEvent &event) const; 108 | }; 109 | #endif 110 | -------------------------------------------------------------------------------- /setup_env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | setup_gpython() { 4 | export PYTHONHOME=/afs/slac/g/glast/ground/GLAST_EXT/redhat5-i686-32bit-gcc41/python/2.7.2 5 | export PATH=$PYTHONHOME/bin:$PATH 6 | } 7 | setup_g64python() { 8 | export PYTHONHOME=/afs/slac/g/glast/ground/GLAST_EXT/redhat5-x86_64-64bit-gcc41/python/2.7.2 9 | export PATH=$PYTHONHOME/bin:$PATH 10 | } 11 | 12 | setup_pythia() { 13 | #export PYTHIA8LOCATION=/afs/slac/g/atlas/c/sw/lcg/external/MCGenerators/pythia8/150/i686-slc5-gcc43-opt/ 14 | export PYTHIA8LOCATION=/u/at/estrauss/afs/WTagger/Pythia8176/ 15 | export PYTHIA8DATA=${PYTHIA8LOCATION}xmldoc/ 16 | export LD_LIBRARY_PATH=${PYTHIA8LOCATION}lib/:$LD_LIBRARY_PATH 17 | } 18 | 19 | setup_hepmc() { 20 | export LD_LIBRARY_PATH=/u/eb/joshgc/mynfs/HepMC/install/lib:$LD_LIBRARY_PATH 21 | export PATH=${PWD}:${PATH} 22 | } 23 | 24 | setup_gcc32() { 25 | export PATH=/afs/slac/g/atlas/d/gcc-alt-435/i686-slc5-gcc43-opt/bin:$PATH 26 | } 27 | 28 | setup_boost() { 29 | export BOOSTINCDIR=/usr/include 30 | export BOOSTLIBLOCATION=/usr/lib 31 | } 32 | 33 | setup_sherpa() { 34 | export SHERPA=/afs/slac/g/atlas/c/sw/lcg/external/MCGenerators/sherpa/1.3.0.2/i686-slc5-gcc43-opt 35 | export SHERPA_INCLUDE_PATH=$SHERPA/include/SHERPA-MC 36 | export SHERPA_SHARE_PATH=$SHERPA/share/SHERPA-MC 37 | export SHERPA_LIBRARY_PATH=$SHERPA/lib/SHERPA-MC 38 | export LD_LIBRARY_PATH=$SHERPA_LIBRARY_PATH:$LD_LIBRARY_PATH 39 | 40 | setup_gcc32 41 | } 42 | 43 | setup_madgraph() { 44 | export MG5=/u/at/estrauss/afs/WTagger/MadGraph5_v1_5_11 45 | } 46 | 47 | setup_sklearn() { 48 | export PYTHONPATH=/u/eb/joshgc/mynfs/scikit-learn/install/lib/python2.7/site-packages:$PYTHONPATH 49 | setup_gpython 50 | } 51 | 52 | setup_photos() { 53 | setup_gcc32 54 | setup_pythia 55 | } 56 | 57 | setup_feynhiggs() { 58 | fpath=/u/eb/joshgc/mynfs/FeynHiggs/FeynHiggs-2.9.1 59 | export MANPATH=$fpath/man/:$MANPATH 60 | export PATH=$fpath/i686-Linux/bin:$PATH 61 | } 62 | 63 | setup_root() { 64 | source /afs/slac/g/glast/ground/GLAST_EXT/redhat5-i686-32bit-gcc41/ROOT/v5.34.03/bin/thisroot.sh 65 | } 66 | 67 | setup_fastjet() { 68 | export LIBPATH=/afs/slac.stanford.edu/package/vdt/vol5/globus/lib:/usr/lib:/lib:$LIBPATH 69 | export LD_LIBRARY_PATH=/afs/slac.stanford.edu/package/vdt/vol5/atlasosgcompat/keepexpat/lib:/afs/slac.stanford.edu/package/vdt/vol5/openldap/lib:/afs/slac.stanford.edu/package/vdt/vol5/lcg/lib:/afs/slac.stanford.edu/package/vdt/vol5/curl/lib:/afs/slac.stanford.edu/package/vdt/vol5/glite/lib64:/afs/slac.stanford.edu/package/vdt/vol5/glite/lib:/afs/slac.stanford.edu/package/vdt/vol5/globus/lib:/afs/slac.stanford.edu/package/vdt/vol5/berkeley-db/lib:/afs/slac.stanford.edu/package/vdt/vol5/expat/lib:/afs/slac/g/atlas/d/gcc-alt-435/x86_64-slc5-gcc43-opt/lib64:/afs/slac/g/atlas/d/gcc-alt-435/x86_64-slc5-gcc43-opt/lib:/afs/slac/g/atlas/d/gcc-alt-432/x86_64-slc5-gcc43-opt/lib64:/afs/slac/g/atlas/d/gcc-alt-432/x86_64-slc5-gcc43-opt/lib:/afs/slac.stanford.edu/package/vdt/vol5/lcg/lib64:$LD_LIBRARY_PATH 70 | } 71 | 72 | setup_herwig() { 73 | export PATH=~joshgc/mynfs/Herwig/install-dir/bin/:${PATH} 74 | export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/afs/slac/g/atlas/c/sw/lcg/external/MCGenerators/lhapdf/5.8.5/i686-slc5-gcc43-opt/lib 75 | export LHAPATH=/afs/slac/g/atlas/c/sw/lcg/external/MCGenerators/lhapdf/5.8.5/share/PDFsets/ 76 | } 77 | 78 | setup_csjets() { 79 | setup_boost 80 | setup_pythia 81 | setup_madgraph 82 | setup_gcc32 83 | setup_sklearn 84 | setup_hepmc 85 | setup_root 86 | setup_fastjet 87 | setup_herwig 88 | 89 | } 90 | 91 | setup_csjets 92 | -------------------------------------------------------------------------------- /src/Evgen.cxx: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | // 3 | // This is the implementation of the non-inlined, non-templated member 4 | // functions of the Evgen class. 5 | // 6 | 7 | #include 8 | #include 9 | #include "Evgen.h" 10 | #include "ThePEG/Config/HepMCHelper.h" 11 | #include "ThePEG/Interface/ClassDocumentation.h" 12 | #include "ThePEG/EventRecord/Particle.h" 13 | #include "ThePEG/Repository/UseRandom.h" 14 | #include "ThePEG/Repository/EventGenerator.h" 15 | #include "ThePEG/Utilities/DescribeClass.h" 16 | 17 | //#include "JetAnalysis.h" 18 | 19 | 20 | 21 | using namespace HerwigWrapper; 22 | 23 | Evgen::Evgen() { 24 | 25 | //JetAnalysis(int saveMaxNJets, int trimJets, float jetMinPt, float jetMinM, float jetMaxM, float jetRadius, int mu, int puSeed, bool doSmear, bool doWTagger, int cellV) { 26 | //jet_analysis = new JetAnalysis(1, 1, 200, 0, 20000, 1.2, 0, 0, false, false, 0); 27 | 28 | props["source"] = "Herwig++"; 29 | props["ME"] = "NoME"; 30 | props["seed"] = "NoSeed"; 31 | } 32 | 33 | Evgen::~Evgen() { 34 | //delete jet_analysis; jet_analysis = 0; 35 | } 36 | 37 | 38 | 39 | #ifndef LWH_AIAnalysisFactory_H 40 | #ifndef LWH 41 | #define LWH ThePEGLWH 42 | #endif 43 | #include "ThePEG/Analysis/LWH/AnalysisFactory.h" 44 | #endif 45 | 46 | void Evgen::analyze(tEventPtr event, long ieve, int loop, int state) { 47 | AnalysisHandler::analyze(event, ieve, loop, state); 48 | std::cout << endl; 49 | std::cout << ieve << ", " << loop << ", " << state << std::endl; 50 | HepMC::GenEvent * hepmc 51 | = HepMCConverter::convert(*event, false, GeV, millimeter); 52 | 53 | hepmc->print(); 54 | 55 | delete hepmc; 56 | 57 | std::stringstream ss; 58 | ss << ieve; 59 | props["eventNumber"] = ss.str(); 60 | //jet_analysis->analyze(hepmc, props); 61 | 62 | // HepMC::GenEvent::particle_const_iterator it; 63 | // for(it=hepmc->particles_begin(); it!=hepmc->particles_end(); ++it){ 64 | // cout << (*it)->pdg_id() << endl; 65 | // } 66 | // hepmc->signal_process_id(); 67 | // Rotate to CMS, extract final state particles and call analyze(particles). 68 | } 69 | 70 | LorentzRotation Evgen::transform(tcEventPtr event) const { 71 | return LorentzRotation(); 72 | // Return the Rotation to the frame in which you want to perform the analysis. 73 | } 74 | 75 | void Evgen::analyze(const tPVector & particles, double weight) { 76 | AnalysisHandler::analyze(particles); 77 | // Calls analyze() for each particle. 78 | } 79 | 80 | void Evgen::analyze(tPPtr, double weight) {} 81 | 82 | void Evgen::dofinish() { 83 | AnalysisHandler::dofinish(); 84 | // *** ATTENTION *** Normalize and post-process histograms here. 85 | } 86 | 87 | void Evgen::doinitrun() { 88 | AnalysisHandler::doinitrun(); 89 | 90 | // *** ATTENTION *** histogramFactory().registerClient(this); // Initialize histograms. 91 | // *** ATTENTION *** histogramFactory().mkdirs("/SomeDir"); // Put histograms in specal directory. 92 | } 93 | 94 | 95 | IBPtr Evgen::clone() const { 96 | return new_ptr(*this); 97 | } 98 | 99 | IBPtr Evgen::fullclone() const { 100 | return new_ptr(*this); 101 | } 102 | 103 | 104 | // If needed, insert default implementations of virtual function defined 105 | // in the InterfacedBase class here (using ThePEG-interfaced-impl in Emacs). 106 | 107 | 108 | 109 | // *** Attention *** The following static variable is needed for the type 110 | // description system in ThePEG. Please check that the template arguments 111 | // are correct (the class and its base class), and that the constructor 112 | // arguments are correct (the class name and the name of the dynamically 113 | // loadable library where the class implementation can be found). 114 | DescribeNoPIOClass 115 | describeHerwigWrapperEvgen("HerwigWrapper::Evgen", "Evgen.so"); 116 | 117 | 118 | void Evgen::Init() { 119 | 120 | static ClassDocumentation documentation 121 | ("There is no documentation for the Evgen class"); 122 | 123 | } 124 | 125 | -------------------------------------------------------------------------------- /include/Evgen.h: -------------------------------------------------------------------------------- 1 | // -*- C++ -*- 2 | #ifndef HerwigWrapper_Evgen_H 3 | #define HerwigWrapper_Evgen_H 4 | // 5 | // This is the declaration of the Evgen class. 6 | // 7 | 8 | #include 9 | #include "ThePEG/Handlers/AnalysisHandler.h" 10 | #include "ThePEG/Vectors/HepMCConverter.h" 11 | 12 | //#include "JetAnalysis.h" 13 | 14 | namespace HerwigWrapper { 15 | 16 | using namespace ThePEG; 17 | 18 | /** 19 | * Here is the documentation of the Evgen class. 20 | * 21 | * @see \ref EvgenInterfaces "The interfaces" 22 | * defined for Evgen. 23 | */ 24 | class Evgen: public AnalysisHandler { 25 | 26 | public: 27 | 28 | /** @name Standard constructors and destructors. */ 29 | //@{ 30 | /** 31 | * The default constructor. 32 | */ 33 | Evgen(); 34 | 35 | /** 36 | * The destructor. 37 | */ 38 | virtual ~Evgen(); 39 | //@} 40 | 41 | public: 42 | 43 | /** @name Virtual functions required by the AnalysisHandler class. */ 44 | //@{ 45 | /** 46 | * Analyze a given Event. Note that a fully generated event 47 | * may be presented several times, if it has been manipulated in 48 | * between. The default version of this function will call transform 49 | * to make a lorentz transformation of the whole event, then extract 50 | * all final state particles and call analyze(tPVector) of this 51 | * analysis object and those of all associated analysis objects. The 52 | * default version will not, however, do anything on events which 53 | * have not been fully generated, or have been manipulated in any 54 | * way. 55 | * @param event pointer to the Event to be analyzed. 56 | * @param ieve the event number. 57 | * @param loop the number of times this event has been presented. 58 | * If negative the event is now fully generated. 59 | * @param state a number different from zero if the event has been 60 | * manipulated in some way since it was last presented. 61 | */ 62 | virtual void analyze(tEventPtr event, long ieve, int loop, int state); 63 | 64 | /** 65 | * Return a LorentzTransform which would put the event in the 66 | * desired Lorentz frame. 67 | * @param event a pointer to the Event to be considered. 68 | * @return the LorentzRotation used in the transformation. 69 | */ 70 | virtual LorentzRotation transform(tcEventPtr event) const; 71 | 72 | /** 73 | * Analyze the given vector of particles. The default version calls 74 | * analyze(tPPtr) for each of the particles. 75 | * @param particles the vector of pointers to particles to be analyzed 76 | * @param weight the weight of the current event. 77 | */ 78 | virtual void analyze(const tPVector & particles, double weight); 79 | 80 | /** 81 | * Analyze the given particle. 82 | * @param particle pointer to the particle to be analyzed. 83 | * @param weight the weight of the current event. 84 | */ 85 | virtual void analyze(tPPtr particle, double weight); 86 | //@} 87 | 88 | protected: 89 | 90 | //JetAnalysis *jet_analysis; 91 | std::map props; 92 | 93 | /** 94 | * Initialize this object. Called in the run phase just before 95 | * a run begins. 96 | */ 97 | virtual void doinitrun(); 98 | 99 | /** 100 | * Finalize this object. Called in the run phase just after a 101 | * run has ended. Used eg. to write out statistics. 102 | */ 103 | virtual void dofinish(); 104 | 105 | 106 | public: 107 | 108 | /** 109 | * The standard Init function used to initialize the interfaces. 110 | * Called exactly once for each class by the class description system 111 | * before the main function starts or 112 | * when this class is dynamically loaded. 113 | */ 114 | static void Init(); 115 | 116 | protected: 117 | 118 | /** @name Clone Methods. */ 119 | //@{ 120 | /** 121 | * Make a simple clone of this object. 122 | * @return a pointer to the new object. 123 | */ 124 | virtual IBPtr clone() const; 125 | 126 | /** Make a clone of this object, possibly modifying the cloned object 127 | * to make it sane. 128 | * @return a pointer to the new object. 129 | */ 130 | virtual IBPtr fullclone() const; 131 | //@} 132 | 133 | 134 | // If needed, insert declarations of virtual function defined in the 135 | // InterfacedBase class here (using ThePEG-interfaced-decl in Emacs). 136 | 137 | 138 | private: 139 | 140 | /** 141 | * The assignment operator is private and must never be called. 142 | * In fact, it should not even be implemented. 143 | */ 144 | Evgen & operator=(const Evgen &); 145 | 146 | }; 147 | 148 | } 149 | 150 | #endif /* HerwigWrapper_Evgen_H */ 151 | -------------------------------------------------------------------------------- /include/Calorimeter.h: -------------------------------------------------------------------------------- 1 | #ifndef CALORIMETER_H 2 | #define CALORIMETER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "fastjet/PseudoJet.hh" 10 | 11 | //Peter Loch's radial energy smearing 12 | #include "DetectorModel.h" 13 | 14 | using namespace std; 15 | using fastjet::PseudoJet; 16 | 17 | class Calorimeter { 18 | private: 19 | //double *m_energy; 20 | vector m_energy; 21 | unsigned int m_nEtaCells; 22 | unsigned int m_nPhiCells; 23 | bool m_phiGoesTo2Pi; 24 | double m_etaMax; 25 | double m_dEta; 26 | double m_dPhi; 27 | 28 | int m_nInteractions; 29 | 30 | bool m_smear; 31 | static DetectorModel::RadialSmearing m_smearer; 32 | 33 | 34 | void 35 | init(unsigned int nEtaCells, unsigned int nPhiCells, 36 | bool phiGoesTo2Pi, double etaMax); 37 | 38 | static double 39 | rectify_phi(double phi, bool goes_to_2PI); 40 | 41 | double etaCloseCell(double eta) const ; 42 | 43 | double phiCloseCell(double phi) const ; 44 | 45 | double 46 | etaFromIndex(unsigned int index) const ; 47 | 48 | double 49 | phiFromIndex(unsigned int index) const ; 50 | 51 | int 52 | makeIndex(double eta, double phi) const; 53 | 54 | unsigned int 55 | makeEtaIndex(double eta) const ; 56 | 57 | unsigned int 58 | makePhiIndex(double phi) const ; 59 | 60 | unsigned int 61 | makeIndex(double val, double low, double high, double n) const ; 62 | 63 | 64 | 65 | public: 66 | Calorimeter(){ 67 | init(50, 63, false, 2.5); 68 | } 69 | 70 | Calorimeter(unsigned int nEtaCells, unsigned int nPhiCells, 71 | bool phiGoesTo2Pi, double etaMax){ 72 | init(nEtaCells, nPhiCells, phiGoesTo2Pi, etaMax); 73 | } 74 | 75 | void setSmear(bool value) { 76 | m_smear = value; 77 | if (m_smear) { 78 | DetectorModel::Grid gridEM(m_nEtaCells, -m_etaMax, m_etaMax, m_nPhiCells); 79 | DetectorModel::Grid gridHAD(m_nEtaCells, -m_etaMax, m_etaMax, m_nPhiCells); 80 | m_smearer.setEmGrid(gridEM); 81 | m_smearer.setHadGrid(gridHAD); 82 | } 83 | } 84 | 85 | const Calorimeter operator+(const Calorimeter &other) const; 86 | Calorimeter & operator+=(const Calorimeter &other); 87 | 88 | 89 | void addEnergy(double e, double eta, double phi); 90 | 91 | void push(const std::vector & jets); 92 | 93 | void push(const PseudoJet & jet) { 94 | std::vector jets; 95 | jets.push_back(jet); 96 | push(jets); 97 | } 98 | 99 | void push(double px, double py, double pz, double e, int pdgid) { 100 | PseudoJet pj(px, py, pz, e); 101 | pj.set_user_index(pdgid); 102 | push(pj); 103 | } 104 | 105 | void 106 | set_nInteractions(const int & nInts) {m_nInteractions = nInts;} 107 | 108 | int 109 | get_nInteractions() const {return m_nInteractions;} 110 | 111 | std::vector getNonZeroCells(); 112 | 113 | void reset(){ 114 | m_energy = vector(m_nEtaCells * m_nPhiCells, 0.0); 115 | set_nInteractions(0); 116 | } 117 | 118 | double get_eta_jet_offset(double eta, double radius) const { 119 | static const double maxEtaStep = ceil(radius/m_dEta - 0.1); 120 | return etaCloseCell(eta - maxEtaStep * m_dEta); 121 | } 122 | 123 | double get_phi_jet_offset(double phi, double radius) const { 124 | static const double maxPhiStep = ceil(radius/m_dPhi - 0.1); 125 | return phiCloseCell(phi - maxPhiStep * m_dPhi); 126 | } 127 | 128 | double 129 | get_cone_energy(double eta, double phi, double radius) const; 130 | 131 | double 132 | get_jet_energy(PseudoJet pj) const{ 133 | double total = 0; 134 | vector pjs = pj.constituents(); 135 | for(unsigned int i_pj; i_pj whitelist, bool use_whitelist) const; 146 | }; 147 | 148 | #endif 149 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Examples Makefile. 3 | # 4 | # M. Kirsanov 07.04.2006 5 | # Modified 18.11.2006 6 | # 26.03.2008 CLHEP dependency removed 7 | 8 | SHELL = /bin/sh 9 | 10 | -include config.mk 11 | PYTHIA8LOCATION= 12 | ifeq (x$(PYTHIA8LOCATION),x) 13 | # PYTHI8LOCATION=/afs/slac/g/atlas/c/sw/lcg/external/MCGenerators/pythia8/150/i686-slc5-gcc43-opt 14 | PYTHI8LOCATION=/u/at/estrauss/afs/WTagger/Pythia8176/share 15 | endif 16 | #PYTHIA8LOCATION=/afs/slac/g/atlas/c/sw/lcg/external/MCGenerators/pythia8/150/i686-slc5-gcc43-opt 17 | PYTHIA8LOCATION=/u/at/estrauss/afs/WTagger/Pythia8176/ 18 | HEPMCLOCATION=/u/eb/joshgc/mynfs/HepMC/install 19 | #-include $(PYTHIA8LOCATION)/config.mk 20 | 21 | ifeq (x$(FASTJETLOCATION),x) 22 | FASTJETLOCATION=/u/eb/joshgc/mynfs/FastJet/fastjet-install/ 23 | endif 24 | 25 | ROOTINC=-I`root-config --incdir` 26 | ROOTLIBS= `root-config --glibs` -lMLP -lTreePlayer 27 | TMVAINC=-I$(ROOTSYS)/tmva/inc/ 28 | TMVALIB=-L$(ROOTSYS)/lib -lTMVA 29 | 30 | WTAGLOCATION=/u/at/estrauss/afs/WTagger/MVATagger/wtag-1.00/ 31 | FASTPRUNELOCATION=/u/at/estrauss/afs/WTagger/MVATagger/FastPrune-0.4.3 32 | FASTPRUNEINC=-I $(FASTPRUNELOCATION)/include 33 | FASTPRUNELIB=-L $(FASTPRUNELOCATION)/lib -lFastPrunePlugin 34 | 35 | ALL_INC=-I../include \ 36 | -I$(PYTHIA8LOCATION)/include \ 37 | -I$(PYTHIA8LOCATION)/examples \ 38 | -I$(HEPMCLOCATION)/include \ 39 | -I $(WTAGLOCATION)/include/ \ 40 | -I $(BOOSTINCDIR) \ 41 | `$(FASTJETLOCATION)/bin/fastjet-config --cxxflags --plugins` \ 42 | -I/u/eb/joshgc/mynfs/FastJetcontrib/fjcontrib-1.002/ 43 | 44 | ALL_LINK= -L$(BOOSTLIBLOCATION) \ 45 | -L$(HEPMCLOCATION)/lib \ 46 | -L$(PYTHIA8LOCATION)/lib/archive \ 47 | -L$(PYTHIA8LOCATION)/lib \ 48 | -lpythia8 -llhapdfdummy -lHepMC \ 49 | -lhepmcinterface $(LIBGZIP) \ 50 | -L$(FASTJETLOCATION)/lib \ 51 | `$(FASTJETLOCATION)/bin/fastjet-config --libs --plugins | sed 's/ -lm / /g'` \ 52 | -lboost_program_options \ 53 | -L$(FASTJETLOCATION)/lib \ 54 | `root-config --glibs` \ 55 | $(TMVALIB) \ 56 | $(FASTPRUNELIB) \ 57 | -lrt ##this is necessary for ns timing (only tested at SLAC) 58 | 59 | # Libraries to include if GZIP support is enabled 60 | ifeq (x$(ENABLEGZIP),xyes) 61 | LIBGZIP=-L$(BOOSTLIBLOCATION) -lboost_iostreams -L$(ZLIBLOCATION) -lz 62 | endif 63 | 64 | baseflags=-O2 -m32 65 | CXXFLAGS=$(baseflags) 66 | 67 | MAINS = pythiaJets hepmcJets 68 | SOURCES = $(shell ls *.cxx | grep -vE '(Evgen|pythiaJets|hepmcJets)') 69 | OBJECTS = $(SOURCES:.cxx=.so) wtag.so 70 | 71 | .PHONY: clean debug all 72 | 73 | all: $(MAINS) 74 | 75 | %.d: %.cxx 76 | $(CXX) $(CXXFLAGS) -MM -MT '$(patsubst %.cxx,%.o,$<)' $< -MF $@ \ 77 | $(ALL_INC) 78 | 79 | # Note: $(CXXFLAGS) is after Fastjet flags as Fastjet includes 80 | # optimisation/debug flags which may be unwanted (e.g. -g -O2) 81 | wtag.so : $(WTAGLOCATION)/src/wtag.cc $(WTAGLOCATION)/include/wtag.h 82 | $(CXX) -o $@ -c $< \ 83 | -I $(WTAGLOCATION)/include/ \ 84 | `$(FASTJETLOCATION)/bin/fastjet-config --cxxflags --plugins` \ 85 | $(ROOTINC) $(TMVAINC) $(FASTPRUNEINC) \ 86 | $(CXXFLAGS) -fPIC -shared 87 | 88 | #$(MAINS): %.so : %.cxx %.d JetAnalysis.so 89 | $(patsubst %, %.so, $(MAINS)): %.so : %.cxx %.d JetAnalysis.so 90 | $(CXX) -o $@ -c $< \ 91 | $(CXXFLAGS) -Wno-shadow -fPIC -shared \ 92 | $(ALL_INC) \ 93 | 94 | %.so: %.cxx ../include/%.h %.d 95 | @echo Using Autogenerated Rule 96 | $(CXX) -o $@ -c $< \ 97 | $(CXXFLAGS) -Wno-shadow -fPIC -shared \ 98 | $(ALL_INC) 99 | 100 | $(MAINS): % : %.so $(PYTHIA8LOCATION)/lib/archive/libpythia8.a $(OBJECTS) 101 | $(CXX) $< $(OBJECTS) -o $@ \ 102 | $(CXXFLAGS) -Wno-shadow \ 103 | $(ALL_LINK) 104 | cp $@ $@.exe 105 | 106 | 107 | #this is the herwig stuff. 108 | #Evgen.so : Evgen.cc Evgen.h 109 | # $(CXX) -shared -fPIC -I/u/eb/joshgc/mynfs/Herwig/install-dir/include \ 110 | # -I/u/eb/joshgc/mynfs/ThePEG/install-dir/include \ 111 | # -I $(HEPMCLOCATION)/include \ 112 | # /afs/slac/g/atlas/c/sw/lcg/external/HepMC/2.03.11/i686-slc5-gcc43-opt/lib/libHepMC.so \ 113 | # -Wl,-export-dynamic \ 114 | # $(CXXFLAGS) $< -o $@ 115 | # cp $@ /u/eb/joshgc/mynfs/Herwig/install-dir/lib/Herwig++/ 116 | 117 | debug: 118 | @#echo PYTHIA8LOCATION IS HERE: $(PYTHIA8LOCATION) 119 | @#$(FASTJETLOCATION)/bin/fastjet-config --cxxflags --plugins 120 | @#$(FASTJETLOCATION)/bin/fastjet-config --libs --plugins 121 | @echo Sources are $(SOURCES) 122 | @echo Objects are $(OBJECTS) 123 | @echo Mains are $(MAINS) 124 | @echo $(patsubst %, %.so, $(MAINS)): %.so 125 | 126 | 127 | # Clean up: remove executables and outdated files. 128 | clean: 129 | rm -rf bin/ 130 | rm -rf *.exe 131 | rm -rf *.o 132 | rm -rf *.so 133 | rm -f *~; rm -f \#*; rm -f core* 134 | -------------------------------------------------------------------------------- /MakeScatterPlot.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from math import sqrt, cos, pi 3 | import numpy as np 4 | import matplotlib.spines 5 | import matplotlib.pyplot as plt 6 | import matplotlib.patches as ptc 7 | from sklearn.decomposition import RandomizedPCA 8 | from fisher import Fisher 9 | 10 | #so that the data dont' keep shifting call to call 11 | np.random.seed(123456789) 12 | 13 | 14 | m1 = np.array([-0.5, 1]) 15 | m2 = np.array([0.5 ,-1]) 16 | cov1 = np.array([[1, 1.5], 17 | [1.5, 2]]) 18 | 19 | xx = cos(pi/7) 20 | rot = np.array([[xx , -1*sqrt(1-xx)], 21 | [sqrt(1-xx), xx ]]) 22 | 23 | m1 = np.dot(m1, rot) 24 | m2 = np.dot(m2, rot) 25 | cov1 = np.dot(cov1, rot) 26 | 27 | d1 = np.random.multivariate_normal(m1, cov1, 100) 28 | d1mean = np.sum(d1, axis=0) / (1.0*d1.shape[0]) 29 | 30 | #cov2 = np.array([[1, 1.5],[1.5,2]]) 31 | #d2 = np.random.multivariate_normal(m2, cov2, 100) 32 | d2 = np.random.multivariate_normal(m2, cov1, 100) 33 | d2mean = np.sum(d2, axis=0) / (1.0*d2.shape[0]) 34 | 35 | x_data_max = max(np.max(d1[:,0]), np.max(d2[:,0])) 36 | y_data_max = max(np.max(d1[:,1]), np.max(d2[:,1])) 37 | x_data_min = min(np.min(d1[:,0]), np.min(d2[:,0])) 38 | y_data_min = min(np.min(d1[:,1]), np.min(d2[:,1])) 39 | 40 | 41 | classmeandiff = d1mean-d2mean 42 | 43 | 44 | alldata = np.concatenate( (d1, d2), axis=0) 45 | alllabels = np.concatenate( ( np.array([0 for i in range(len(d1))]), np.array([1 for i in range(len(d2))]) ), axis=0) 46 | meanall = np.sum(alldata, axis=0) / (1.0*alldata.shape[0]) 47 | 48 | pca = RandomizedPCA(2) 49 | pca.fit( alldata ) 50 | d1pca = pca.transform(d1) 51 | d2pca = pca.transform(d2) 52 | mean1pca = pca.transform(d1mean) 53 | pcasign = np.array([1.0, 1.0]) 54 | if mean1pca[0]<0: pcasign[0] = -1.0 55 | if mean1pca[1]<0: pcasign[1] = -1.0 56 | 57 | 58 | fish = Fisher(norm_covariance=True) 59 | fish.fit_multiclass(alldata, alllabels, use_total_scatter=False, solution_norm="N", sigma_sqrd=1e-8, tol=5e-3, print_timing=False) 60 | d1fish = fish.transform(d1) 61 | d2fish = fish.transform(d2) 62 | fishsign=1.0 63 | mean1fish = fish.transform(d1mean) 64 | if mean1fish[0]<0: fishsign = -1.0 65 | 66 | 67 | c_sig = 'g' 68 | c_bkg = 'r' 69 | to_do = [(classmeandiff , 'Class Mean Difference', '#04819e'), 70 | (pca.components_[0], 'First PCA Component' , '#a65200'), 71 | (pca.components_[1], 'Second PCA Component' , '#ff7f00'), 72 | (fish.w_[0] , 'Fisher Discriminant' , '#1435ad'), 73 | ] 74 | 75 | #for doVector in (False,): 76 | for doVector in (True, False): 77 | for n_subs in range(3,4): 78 | fig = plt.figure(figsize=(3.7*2,3*2)) 79 | ax = plt.subplot2grid((4,5), (0,0), colspan=4, rowspan=4) 80 | ax.scatter(d1[:,0], d1[:,1], c=c_sig, edgecolor=c_sig, lw=0) 81 | ax.scatter(d2[:,0], d2[:,1], c=c_bkg, edgecolor=c_bkg, lw=0) 82 | 83 | 84 | patches = [plt.Rectangle((1,1), 1, 1, ec='w', fc='w')]*4 85 | names = ['']*4 86 | x = meanall[0] 87 | y = meanall[1] 88 | ll = 3 89 | 90 | #to be fair i should use both datasets. 91 | #Lifes not fair and neither am I 92 | max_dx = np.max(np.abs(d1[:,0] - meanall[0])) 93 | max_dy = np.max(np.abs(d1[:,1] - meanall[0])) 94 | for ii, li, in enumerate(to_do[:n_subs+1]): 95 | ra, name, color = li 96 | dx = ll * ra[0]/sqrt(ra[0] ** 2 + ra[1]**2) 97 | dy = ll * ra[1]/sqrt(ra[0] ** 2 + ra[1]**2) 98 | if doVector: 99 | if dy < 0: 100 | dx *= -1 101 | dy *= -1 102 | obj = ax.arrow(x, y, dx, dy, color=color, 103 | head_width=0.20, head_length=0.2, 104 | linewidth=3, label=name) 105 | else: 106 | dx, dy = -dy, dx 107 | factor = min(max_dy/abs(dy), max_dx/abs(dx)) 108 | dx *= factor 109 | dy *= factor 110 | obj = ax.arrow(x-dx, y-dy, 2*dx, 2*dy, color=color, 111 | head_width=0.001, head_length=0.001, 112 | linewidth=3, label=name, linestyle='solid') 113 | 114 | patches[ii] = obj 115 | names [ii] = name 116 | 117 | ax.legend(patches, names, loc=4, fontsize=14, 118 | frameon=False) 119 | ax.get_legend().set_title( 120 | 'Discriminant Directions' if doVector else 'Discriminanting Planes', 121 | prop={'size':18}) 122 | 123 | 124 | ax.set_title("Toy Data", fontsize=18) 125 | ax.set_xticks([]) 126 | ax.set_yticks([]) 127 | 128 | ax.set_xlim(-6, 6) 129 | ax.set_ylim(-7, 5) 130 | #ax.set_axis_off() 131 | 132 | _axes = [] 133 | _to_hist = [ 134 | (np.dot(d1, classmeandiff), np.dot(d2, classmeandiff), 'Class Means'), 135 | (pcasign[0]*d1pca[:,0], pcasign[0]*d2pca[:,0], 'First PCA'), 136 | (pcasign[1]*d1pca[:,1], pcasign[1]*d2pca[:,1], 'Second PCA'), 137 | (fishsign*d1fish[:,0], fishsign*d2fish[:,0] , 'Fisher'), 138 | ] 139 | 140 | for ii, li in enumerate(_to_hist[:n_subs+1]): 141 | _axes.append(plt.subplot2grid((4,5), (ii, 4))) 142 | if ii==0: 143 | plt.title('Projections', fontsize=18) 144 | _axes[-1].hist(li[0], 10, normed=1, facecolor=c_sig, alpha=0.5) 145 | _axes[-1].hist(li[1], 10, normed=1, facecolor=c_bkg, alpha=0.5) 146 | _axes[-1].set_xticks([]) 147 | _axes[-1].set_yticks([]) 148 | _axes[-1].set_xlabel(li[2], size='medium') 149 | for child in _axes[-1].get_children(): 150 | if isinstance(child, matplotlib.spines.Spine): 151 | child.set_color(to_do[ii][2]) 152 | 153 | plt.show() 154 | #plt.savefig('demo_linear_%s_%d.png' % ('directions' if doVector else 'planes', n_subs)) 155 | -------------------------------------------------------------------------------- /InputCleaner.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | '''Library to ingest and clean lines from file/stdin; 3 | they are evaled into python objects and returned 4 | ''' 5 | 6 | import time 7 | __author__ = 'Josh Cogan' 8 | 9 | def smart_open(fname, flag='r'): 10 | '''Handle normal and gzipped files seamlessly''' 11 | if fname[-6:] == 'tar.gz' or fname[-4:] == '.tgz': 12 | import gzip 13 | return gzip.open(fname, flag) 14 | return open(fname, flag) 15 | 16 | 17 | class InputCleanerGen: 18 | def __init__(self, filenames=[], lastResort=None, wait=False, search=None, repl=None): 19 | self.listOfLines = [] 20 | self.filenames = filenames 21 | self.lastResort = lastResort 22 | self.wait = wait 23 | self.search = search 24 | 25 | if repl is None: 26 | self.repl = r'\1' 27 | else: 28 | self.repl = repl 29 | self._open_file_ = None 30 | 31 | old = time.time() 32 | self.nLines = sum(1 for ff in filenames for line in smart_open(ff)) 33 | #print 'It took %d seconds to count the %d lines' % (time.time() - old, self.nLines) 34 | 35 | def size(self): 36 | '''Max possible, but if search is not none, actual lines will be 37 | less''' 38 | return self.nLines 39 | 40 | def getGen(self, maxReturned=-1): 41 | count = 0 42 | 43 | if isinstance(maxReturned, float): maxReturned = int(maxReturned) 44 | if not isinstance(maxReturned, int): maxReturned = -1 45 | 46 | 47 | sandbox = {} 48 | for filename in self.filenames: 49 | self._open_file_ = smart_open(filename, 'r') 50 | for line in self._open_file_: 51 | safe = InputCleanerGen.madeSafe(line, self.search, self.repl) 52 | if safe is None: 53 | continue 54 | 55 | if maxReturned >= 0 and count >= maxReturned: 56 | break 57 | 58 | count += 1 59 | yield InputCleanerGen.typify(eval(safe, sandbox)) 60 | 61 | 62 | self._open_file_.close() 63 | self._open_file_ = None 64 | 65 | if maxReturned >= 0 and count >= maxReturned: 66 | return 67 | 68 | def __del__(self): 69 | if self._open_file_ is not None: 70 | self._open_file_.close() 71 | 72 | 73 | @staticmethod 74 | def madeSafe(dirty, search, repl): 75 | '''Output from this function is "safe" for eval''' 76 | import sys 77 | import re 78 | 79 | if search is not None and None is re.search(search, dirty): 80 | return None 81 | 82 | if search is not None: 83 | dirty = re.sub(search, repl, dirty) 84 | words = set(re.findall('(\w+)', dirty)) 85 | 86 | if len( words & set(('import', 'os', 'sys'))) > 0: 87 | print 'WOW DANGEROUS INPUT\n%s\nGoodbye' % dirty 88 | sys.exit(1) 89 | 90 | dirty = dirty.strip() 91 | return dirty if len(dirty) > 0 else None 92 | 93 | @staticmethod 94 | def typify(di): 95 | typed = {} 96 | for k,v in di.iteritems(): 97 | try: 98 | val = float(v) 99 | if val == 0: 100 | val = 0 101 | elif (val - int(val))/val < 1e-6: 102 | val = int(val) 103 | except ValueError: 104 | val = v 105 | except TypeError: 106 | val = v 107 | 108 | typed[k] = val 109 | 110 | return typed 111 | 112 | class InputCleaner: 113 | cls_search = r'^(.*)$' 114 | cls_repl = r'\1' 115 | 116 | def __init__(self, filenames=[], lastResort=None, wait=False, search=cls_search, repl=cls_repl): 117 | self.listOfLines = [] 118 | self.filenames = filenames 119 | self.lastResort = lastResort 120 | self.wait = wait 121 | self.search = search 122 | self.repl = repl 123 | 124 | if not self.wait: 125 | self.go() 126 | 127 | def go(self): 128 | for filename in self.filenames: 129 | fh = smart_open(filename, 'r') 130 | self._ingest(fh) 131 | fh.close() 132 | 133 | if len(self.filenames) == 0: 134 | print 'Falling back on stdin!' 135 | self._ingest(self.lastResort) # assumes its sys.stdin 136 | 137 | def add(self, fHandle): 138 | self.inputs.append(fHandle) 139 | 140 | def _ingest(self, fHandle):#, mapAndFilter=None): 141 | '''Here we extract all the science from a unix file''' 142 | sandbox = {} 143 | safeLines = [InputCleaner.madeSafe(line, self.search, self.repl) 144 | for line in fHandle] 145 | listOfDicts = [InputCleaner.typify(eval(line, sandbox)) 146 | for line in safeLines if line is not None] 147 | self.listOfLines.extend([di for di in listOfDicts]) 148 | 149 | def clear(self): 150 | self.inputs = None 151 | self.lastResort = None 152 | self.flush() 153 | 154 | def flush(self): 155 | self.listOfLines = [] 156 | 157 | def excreteList(self): 158 | ret = list(self.listOfLines) 159 | return ret 160 | 161 | def excreteList(self): 162 | ret = list(self.listOfLines) 163 | return ret 164 | 165 | 166 | @staticmethod 167 | def madeSafe(dirty, search='#.*', repl=''): 168 | '''Output from this function is "safe" for eval''' 169 | import sys 170 | import re 171 | 172 | if search is not None and None is re.search(search, dirty): 173 | return None 174 | 175 | if search is not None: 176 | dirty = re.sub(search, repl, dirty) 177 | words = set(re.findall('(\w+)', dirty)) 178 | 179 | if len( words & set(('import', 'os', 'sys'))) > 0: 180 | print 'WOW DANGEROUS INPUT\n%s\nGoodbye' % dirty 181 | sys.exit(1) 182 | 183 | dirty = dirty.strip() 184 | return dirty if len(dirty) > 0 else None 185 | 186 | @staticmethod 187 | def typify(di): 188 | typed = {} 189 | for k,v in di.iteritems(): 190 | try: 191 | val = float(v) 192 | if val == 0: 193 | val = 0 194 | elif (val - int(val))/val < 1e-6: 195 | val = int(val) 196 | except ValueError: 197 | val = v 198 | except TypeError: 199 | val = v 200 | 201 | typed[k] = val 202 | 203 | return typed 204 | 205 | if __name__ == '__main__': 206 | 207 | import sys 208 | ic = InputCleaner(sys.argv[1:], sys.stdin) 209 | 210 | print ic.excreteList() 211 | -------------------------------------------------------------------------------- /src/ExtendableJet.cxx: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "ExtendableJet.h" 10 | 11 | using namespace std; 12 | using fastjet::PseudoJet; 13 | 14 | void 15 | ExtendableJet::init(PseudoJet &pJet, 16 | Calorimeter &filledCalo, 17 | vector &pu_calos, 18 | double radius, 19 | unsigned int nSubjets, 20 | double subjetRadius){ 21 | jet = pJet; 22 | //evt = event; 23 | calo = filledCalo; 24 | m_pu_calos = pu_calos; 25 | m_nSubjets = nSubjets; 26 | m_subjetRadius = subjetRadius; 27 | m_radius = radius; 28 | //http://www.fastjet.fr/repo/doxygen-3.0.3/10-subjets_8cc_source.html 29 | m_dcut = pow(subjetRadius/radius, 2); //don't know what dcut means 30 | 31 | setProperty("radius", radius); 32 | setProperty("subjetRadius", subjetRadius); 33 | setProperty("nParts", jet.constituents().size()); 34 | setProperty("pt" , jet.pt ()); 35 | setProperty("eta", jet.eta()); 36 | setProperty("phi", jet.phi_std()); 37 | setProperty("rap", jet.rap()); 38 | setProperty("e" , jet.e ()); 39 | setProperty("m" , jet.m ()); 40 | 41 | //setProperty("nTracks", getNTracks()); 42 | setProperty("npv", calo.get_nInteractions()); 43 | 44 | 45 | unsigned int _idArray[] = {211, 321, 2212, 11, 13}; 46 | chargedIds = set(_idArray, _idArray + 5); 47 | } 48 | 49 | ////this is broken at the moment, since 50 | //// user_id was hijacked for calo index 51 | //unsigned int 52 | //ExtendableJet::getNTracks() const { 53 | // return 0; 54 | // unsigned int pdgId = 0; 55 | // unsigned int nTracks = 0; 56 | // int index = 0; 57 | // 58 | // std::vector parts = this->jet.constituents(); 59 | // std::vector::iterator it; 60 | // for (it=parts.begin(); it!=parts.end(); it++){ 61 | // 62 | // index = (*it).user_index(); 63 | // if(index < 0) continue; 64 | // 65 | // pdgId = abs(this->evt[index].id()); 66 | // if (chargedIds.count(pdgId) == 1) ++nTracks; 67 | // } 68 | // 69 | // return nTracks; 70 | //} 71 | // 72 | 73 | double 74 | ExtendableJet::get_cos_theta(const vector &subjets) const 75 | { 76 | assert(subjets.size()>1); 77 | 78 | PseudoJet boost = subjets[0] + subjets[1]; 79 | PseudoJet unb_0 = PseudoJet(subjets[0]).unboost(boost); 80 | PseudoJet unb_1 = PseudoJet(subjets[1]).unboost(boost); 81 | 82 | double ct_0 = 83 | unb_0.px() * boost.px() + 84 | unb_0.py() * boost.py() + 85 | unb_0.pz() * boost.pz(); 86 | double ct_1 = 87 | unb_1.px() * boost.px() + 88 | unb_1.py() * boost.py() + 89 | unb_1.pz() * boost.pz(); 90 | 91 | ct_0 /= sqrt( 92 | unb_0.px() * unb_0.px() + 93 | unb_0.py() * unb_0.py() + 94 | unb_0.pz() * unb_0.pz()); 95 | ct_1 /= sqrt( 96 | unb_1.px() * unb_1.px() + 97 | unb_1.py() * unb_1.py() + 98 | unb_1.pz() * unb_1.pz()); 99 | 100 | double boost_mag = sqrt( 101 | boost.px() * boost.px() + 102 | boost.py() * boost.py() + 103 | boost.pz() * boost.pz()); 104 | 105 | ct_0 /= boost_mag; 106 | ct_1 /= boost_mag; 107 | 108 | // ct_0 > ct_1 98% of the time in W-200GeV r=1.2 109 | //cout << "#B" << ct_0 << ", " << ct_1 << endl; 110 | 111 | return ct_0; 112 | } 113 | 114 | //level==0 no cells 115 | //level==1 only whitelisted cells 116 | //level==2 all cells in jet regardless of trimming 117 | string 118 | ExtendableJet::toString(int verbosity_level) const { 119 | map::const_iterator it; 120 | 121 | std::stringstream ss; 122 | int pdgId = 0; 123 | int index = 0; 124 | 125 | double origin_eta = calo.get_eta_jet_offset(jet.eta(), m_radius); 126 | double origin_phi = calo.get_phi_jet_offset(jet.phi(), m_radius); 127 | double rel_phi; 128 | 129 | ss << "{"; 130 | for (it=properties.begin() ; it != properties.end(); it++) 131 | { 132 | ss << "'" << (*it).first << "': " ; 133 | ss << "'" << (*it).second << "', "; 134 | } 135 | 136 | if (verbosity_level>0){ 137 | std::set whitelist; 138 | for(unsigned int iCon = 0; iCon < jet.constituents().size(); ++iCon) 139 | { 140 | whitelist.insert(jet.constituents()[iCon].user_index()); 141 | } 142 | 143 | ss << calo.jetToString(jet.eta(), 144 | jet.phi_std(), 145 | m_radius, 146 | whitelist, 147 | verbosity_level==1 148 | ); 149 | } 150 | 151 | //vector subjets = fastjet::sorted_by_pt( 152 | // jet.exclusive_subjets(m_dcut)); 153 | vector subjets = jet.pieces(); 154 | 155 | subjets = fastjet::sorted_by_pt(jet.pieces()); 156 | 157 | ss << "'cos_theta': '"; 158 | if (subjets.size() > 1) ss << get_cos_theta(subjets); 159 | else ss << -2; 160 | ss << "', "; 161 | 162 | ss << "'subjet_dr': '"; 163 | if (subjets.size() < 2) ss << -1; 164 | else ss << subjets[0].delta_R(subjets[1]); 165 | ss << "', "; 166 | 167 | ss << "'y_balance': '"; 168 | if (subjets.size() < 2) ss << -1; 169 | else ss << subjets[1].pt() * subjets[0].delta_R(subjets[1])/jet.m(); 170 | ss << "', "; 171 | 172 | ss << "'log_balance': '"; 173 | if (subjets.size() < 2) ss << -1; 174 | else ss << -1 * log(1-subjets[0].pt()/jet.pt()); 175 | ss << "', "; 176 | 177 | ss << "'subjets': ["; 178 | for (unsigned int ii=0; ii < min(m_nSubjets, subjets.size()); ++ii){ 179 | PseudoJet sj = subjets[ii]; 180 | ss << "(" << sj.pt(); 181 | ss << ", " << sj.eta(); 182 | ss << ", " << sj.phi_std(); 183 | ss << "),"; 184 | } 185 | ss << "],"; 186 | 187 | 188 | ss << "'rel_subjets': ["; 189 | for (unsigned int ii=0; ii < min(m_nSubjets, subjets.size()); ++ii){ 190 | PseudoJet sj = subjets[ii]; 191 | 192 | rel_phi = sj.phi_std() - origin_phi; 193 | rel_phi += (rel_phi < 0 ? 2*M_PI : 0); 194 | 195 | ss << "(" << sj.pt(); 196 | ss << ", " << sj.eta()-origin_eta; 197 | ss << ", " << rel_phi; 198 | ss << "),"; 199 | } 200 | 201 | vector pu_energies; 202 | double pu_e = 0; 203 | for(unsigned int i_calo=0; i_calo < m_pu_calos.size(); ++i_calo){ 204 | pu_energies.push_back(m_pu_calos[i_calo].get_jet_energy(jet)); 205 | pu_e += pu_energies[i_calo]; 206 | } 207 | 208 | ss << "], 'pu_energies': ["; 209 | for(unsigned int i_e=0; i_e 3 | #include 4 | #include 5 | #include 6 | #include 7 | //#include 8 | 9 | //things josh installed 10 | #include "boost/program_options.hpp" 11 | 12 | #include "HepMC/IO_HEPEVT.h" 13 | #include "HepMC/IO_GenEvent.h" 14 | 15 | //physics things josh wrote 16 | #include "JetAnalysis.h" 17 | 18 | #define HAS_NS_TIME 19 | #define _USE_MATH_DEFINES 20 | 21 | using std::cout; 22 | using std::endl; 23 | using std::string; 24 | using std::map; 25 | namespace po = boost::program_options; 26 | 27 | int getSeed(int optSeed){ 28 | if (optSeed > -1) return optSeed; 29 | 30 | int timeSeed = time(NULL); 31 | 32 | #ifdef HAS_NS_TIME 33 | { 34 | timespec tp; 35 | if ( 0 == clock_gettime(CLOCK_REALTIME, &tp)) timeSeed = tp.tv_nsec; 36 | } 37 | #endif 38 | 39 | //http://arxiv.org/abs/1005.4117 supposed to keep collisions down to 40 | //My seed is strong... 41 | return abs(((timeSeed*181)*((getpid()-83)*359))%104729); 42 | } 43 | 44 | 45 | int main(int argc, char* argv[]) { 46 | cout << "Called as: "; 47 | for(int ii=0; ii(&optSource)->default_value("HepMC"), 74 | "Generator for HepMC input") 75 | ("metype", po::value(&optME)->default_value('g') 76 | , "g,q,v,t,W") 77 | ("lepcharge", po::value (&optLepQ) ->default_value(1) 78 | , "Charge of lepton desired in final state, only for ME ={v, t, W}. 1=l^+, -1=l^-, 0= All lepton flavors, any other value = no lepton (all hadronic),") 79 | ("seed", po::value(&optSeed) ->default_value(-1) 80 | , "Random seed. The default, -1, means the HepMC source seed is unknown") 81 | ("savemaxnjets", po::value(&optSaveMaxNJets) ->default_value(-1) 82 | , "Max number of jets to save. Default, -1, saves all jets (which satisfy other selectons)") 83 | ("nevents", po::value (&optNEvents) ->default_value(1) 84 | , "# Events to generate") 85 | ("cellv", po::value(&optCellV) ->default_value(1) 86 | , "Control how many and which cells to output. 0 shows no cells, 1 (default) shows only those that survive trimming and 2 shows all cells in a jet.") 87 | ("meminpt" , po::value(&optMEMinPt) ->default_value(-1.0) 88 | , "PTHatMin used in HepMC File(GeV)") 89 | ("memaxpt" , po::value(&optMEMaxPt) ->default_value(-1.0) 90 | , "PTHatMax used in HepMC File(GeV)") 91 | ("trimjet", po::value (&optTrimJet) ->default_value(1) 92 | , "To run trimming or not. Any value other than 1 (default) disables trimming.") 93 | ("jetminpt" , po::value(&optJetMinPt) ->default_value(25.0) 94 | , "Jet PTMin (GeV)") 95 | ("jetmaxpt" , po::value(&optJetMaxPt) ->default_value(99999.0) 96 | , "Jet PTMax (GeV)") 97 | ("jetminm" , po::value(&optJetMinM) ->default_value(0) 98 | , "Jet Min Mass (GeV)") 99 | ("jetmaxm" , po::value(&optJetMaxM) ->default_value(20000) 100 | , "Jet Max Mass (GeV)") 101 | ("rad" , po::value(&optJetRadius) ->default_value(0.4) 102 | , "Jet Finder Radius") 103 | ("mu" , po::value(&optMu) ->default_value(0.0) 104 | , "Average Int./Cross") 105 | ("smear" , "Turn on radial energy smearing") 106 | ("wtagger", "Turn on MVA Tagger output") 107 | ("input-file", po::value< vector >(), "input file") 108 | ("n_B" , po::value(&optNB) ->default_value(-1) 109 | , "Exactl number of b-hadrons per-jet (-1 for no cut)") 110 | ; 111 | 112 | po::positional_options_description p; 113 | p.add("input-file", -1); 114 | 115 | po::variables_map vm; 116 | //po::store(po::parse_command_line(argc, argv, desc), vm); 117 | po::store(po::command_line_parser(argc, argv). 118 | options(desc).positional(p).run(), vm); 119 | po::notify(vm); 120 | 121 | if (vm.count("help")>0){ 122 | cout << desc << "\n"; 123 | return 1; 124 | } 125 | 126 | const char MATRIX_ELEMENT = tolower(optME); 127 | const int LEP_CHARGE = optLepQ; 128 | const int N_EVENTS = optNEvents; 129 | const int R_SEED = getSeed(optSeed); 130 | const int ME_PT_MIN = optMEMinPt; 131 | const int ME_PT_MAX = optMEMaxPt; 132 | const int DO_TRIMMING = optTrimJet; 133 | const float MU = optMu; 134 | 135 | std::stringstream ss; 136 | 137 | JetAnalysis jet_analysis(optSaveMaxNJets, 138 | DO_TRIMMING, 139 | optJetMinPt, 140 | optJetMaxPt, 141 | optJetMinM, 142 | optJetMaxM, 143 | optJetRadius, 144 | optNB, 145 | MU, 146 | R_SEED, 147 | (vm.count("smear")>0 ? true : false), 148 | (vm.count("wtagger")>0 ? true : false), 149 | optCellV 150 | ); 151 | 152 | map props; 153 | props["source"] = optSource; 154 | 155 | ss.clear(); ss.str(""); 156 | ss << MATRIX_ELEMENT; 157 | props["ME"] = ss.str(); 158 | 159 | ss.clear(); ss.str(""); 160 | ss << R_SEED; 161 | props["seed"] = ss.str(); 162 | 163 | HepMC::GenEvent *gevt = new HepMC::GenEvent(); 164 | 165 | if (vm.count("input-file")) { 166 | cout << "Input files are: " << endl; 167 | vector::const_iterator iFile = vm["input-file"].as< vector >().begin(); 168 | vector::const_iterator iFileEnd = vm["input-file"].as< vector >().end(); 169 | for (; iFile != iFileEnd; ++iFile) { 170 | cout << *iFile << "\n"; 171 | 172 | HepMC::IO_GenEvent ascii_in(iFile->c_str(),std::ios::in); 173 | 174 | gevt = ascii_in.read_next_event(); 175 | int iEvent = 0; 176 | while ( (N_EVENTS <= 0 || iEvent < N_EVENTS) && gevt) { 177 | iEvent++; 178 | if ( iEvent%50==1 ) std::cout << "Processing Event Number " << iEvent 179 | << " its # " << gevt->event_number() 180 | << std::endl; 181 | 182 | 183 | ss.clear(); ss.str(""); 184 | ss << iEvent; 185 | props["eventNumber"] = ss.str(); 186 | 187 | jet_analysis.analyze(gevt, props); 188 | 189 | delete gevt; 190 | gevt = ascii_in.read_next_event(); 191 | 192 | } // while events 193 | 194 | delete gevt; 195 | } // for input files 196 | 197 | } // if input-file 198 | 199 | 200 | // for (int iEvent = 0; iEvent < N_EVENTS; ++iEvent) { 201 | 202 | // ss.clear(); ss.str(""); 203 | // ss << iEvent; 204 | // props["eventNumber"] = ss.str(); 205 | 206 | // delete gevt; 207 | // gevt = new HepMC::GenEvent(); 208 | 209 | // jet_analysis.analyze(gevt, props); 210 | // continue; 211 | 212 | // } 213 | return 0; 214 | } 215 | -------------------------------------------------------------------------------- /runMadgraph.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import time 3 | import sys 4 | import math 5 | import sys 6 | import os 7 | 8 | ##### 9 | samples = { 10 | 'h' : ('WHbb_up_to_2j', os.getenv('HomeDir', '.') + '/data/WHbb_up_to_2j.dat'), 11 | 'g' : ('Wbb_up_to_2j' , os.getenv('HomeDir', '.') + '/data/Wbb_up_to_2j.dat' ), 12 | } 13 | 14 | def runArgs(args): 15 | args = " ".join(args) 16 | print args 17 | result = subprocess.call(args, shell=True) 18 | if result != 0: 19 | raise ValueError('Returned %d for %s' % (result, args)) 20 | return result 21 | 22 | def modifyCards(configName, nevents, seed, jetminpt, jetminm): 23 | import re 24 | r_run = [ (r'(.*)[0-9]* *= nevents(.*)', ' %d = nevents' % nevents ), 25 | (r'(.*)[0-9]* *= iseed(.*)' , ' %d = iseed' % seed ), 26 | (r'(.*)[0-9]* *= mmbb(.*)' , ' %d = mmbb' % max(jetminm - 20, 0) ), 27 | (r'(.*)[0-9]* *= ptllmin(.*)', ' %d = ptllmin' % max(jetminpt - 30,0) ), 28 | ] 29 | 30 | run_card = open('%s/Cards/run_card.dat' % samples[configName][0]).read() 31 | for pattern, replacement in r_run: 32 | 33 | print "="*5 34 | print pattern 35 | print replacement 36 | sys.stdout.flush() 37 | 38 | m = re.search(pattern, run_card) 39 | if m: 40 | run_card = run_card.replace(m.group(0), replacement + ' ! local modification') 41 | else: 42 | raise ValueError('No patter matching %s' % pattern) 43 | 44 | open('%s/Cards/run_card.dat' % samples[configName][0], 'w').write(run_card) 45 | 46 | print "EAS: start run_card" 47 | print run_card 48 | print "EAS: end run_card" 49 | sys.stdout.flush() 50 | 51 | def runMadgraph(configName, nevents, seed, jetminpt, jetmaxpt, jetminm, jetmaxm): 52 | print "runMadgraph %s:" % configName 53 | result = 0 54 | 55 | #result += runArgs(args) 56 | 57 | args = [os.getenv('MG5') + '/bin/mg5', '-f', samples[configName][1]] 58 | result += runArgs(args) 59 | 60 | modifyCards(configName, nevents, seed, jetminpt, jetminm) 61 | 62 | args = ['%s/bin/generate_events' % samples[configName][0], '-f'] 63 | result += runArgs(args) 64 | 65 | args = ['gunzip', '%s/Events/run_01/unweighted_events.lhe.gz' % samples[configName][0]] 66 | result += runArgs(args) 67 | 68 | print "@@ Start LHE File" 69 | print open('%s/Events/run_01/unweighted_events.lhe' % samples[configName][0]).read() 70 | print "@@ End LHE File" 71 | 72 | return result 73 | 74 | def runPythiaJets(seed, metype 75 | , savemaxnjets, nevents 76 | , cellv, trimjet 77 | , jetminpt, jetmaxpt 78 | , jetminm, jetmaxm 79 | , rad, mu, smear 80 | , wtagger, input_file 81 | ): 82 | 83 | print "runPythiaJets:" 84 | 85 | args = ["pythiaJets.exe"] 86 | args += ["--seed=%s" % str(seed) , "--matching" , 87 | "--metype=%s" % str(metype) , "--LHEFile=%s" % input_file , 88 | "--savemaxnjets=%s" % str(savemaxnjets) , "--nevents=%s" % str(nevents) , 89 | "--cellv=%s" % str(cellv) , "--trimjet=%s" % str(trimjet) , 90 | "--jetminpt=%s" % str(jetminpt) , "--jetmaxpt=%s" % str(jetmaxpt) , 91 | "--jetminm=%s" % str(jetminm) , "--jetmaxm=%s" % str(jetmaxm) , 92 | "--rad=%s" % str(rad) , "--mu=%s" % str(mu) , 93 | ] 94 | 95 | if smear: 96 | args.append("--smear") 97 | if wtagger: 98 | args.append("--wtagger") 99 | 100 | result = runArgs(args) 101 | 102 | return result 103 | 104 | def getSeed(optSeed): 105 | if optSeed > -1: return optSeed 106 | 107 | from time import time 108 | import os 109 | timeSeed = int(time() * pow(10,9)) 110 | 111 | return abs(((timeSeed*181)*((os.getpid()-83)*359))%104729) 112 | 113 | if __name__ == '__main__': 114 | import sys 115 | import argparse 116 | import subprocess 117 | 118 | print "Called with:" 119 | print " ".join(sys.argv) 120 | print "HomeDir: ", os.getenv("HomeDir", "-1") 121 | print "" 122 | 123 | 124 | parser = argparse.ArgumentParser(description='Run MadGraph + pythiaJets.') 125 | parser.add_argument('--seed' , default=-1 , type=int , help='The random number generator seed (-1 finds a random seed)') 126 | parser.add_argument('--savemaxnjets', default=-1 , type=int , help='Max number of jets to save. Default, -1, saves all jets (which satisfy other selectons)') 127 | parser.add_argument('--nevents' , default=100 , type=int , help='The generator number of events') 128 | parser.add_argument('--metype' , default='h' , type=str , choices = ['h', 'g'] , help='Matrix element type') 129 | parser.add_argument('--lepcharge' , default=1 , type=int , choices = [-1, 1, 0] , help='') 130 | parser.add_argument('--meminpt' , default=0 , type=int , help='') 131 | parser.add_argument('--memaxpt' , default=20000 , type=int , help='') 132 | parser.add_argument('--jetminpt' , default=0 , type=int , help='Jet PTMin (GeV)') 133 | parser.add_argument('--jetmaxpt' , default=20000 , type=int , help='Jet PTMax (GeV)') 134 | parser.add_argument('--jetminm' , default=0 , type=int , help='Jet Min Mass (GeV)') 135 | parser.add_argument('--jetmaxm' , default=20000 , type=int , help='Jet Max Mass (GeV)') 136 | parser.add_argument('--cellv' , default=1 , type=int , choices = [0, 1] , help='Control how many and which cells to output. 0 shows no cells, 1 (default) shows only those that survive trimming and 2 shows all cells in a jet.') 137 | parser.add_argument('--trimjet' , default=1 , type=int , help='To run trimming or not. Any value other than 1 (default) disables trimming.') 138 | parser.add_argument('--rad' , default=0.4 , type=float , help='Jet Finder Radius') 139 | parser.add_argument('--mu' , default=0.0 , type=float , help='Average Int./Cross') 140 | parser.add_argument('--smear' , default=False , action='store_true' , help='Turn on radial energy smearing') 141 | parser.add_argument('--wtagger' , default=False , action='store_true' , help='Turn on MVA Tagger output') 142 | 143 | args = parser.parse_args() 144 | 145 | args.seed = getSeed(args.seed) 146 | 147 | sys.stdout.flush() 148 | print "" 149 | print "-+"*50 150 | print "runMadgraph" 151 | print runMadgraph(args.metype, args.nevents, args.seed 152 | , args.jetminpt, args.jetmaxpt 153 | , args.jetminm, args.jetmaxm 154 | ) 155 | 156 | sys.stdout.flush() 157 | print "" 158 | print "-+"*50 159 | print "runPythiaJets" 160 | print runPythiaJets(seed=args.seed, metype=args.metype 161 | , savemaxnjets=args.savemaxnjets, nevents=args.nevents 162 | , cellv=args.cellv, trimjet=args.trimjet 163 | , jetminpt=args.jetminpt, jetmaxpt=args.jetmaxpt 164 | , jetminm=args.jetminm, jetmaxm=args.jetmaxm 165 | , rad=args.rad, mu=args.mu, smear=args.smear 166 | , wtagger=args.wtagger, input_file='%s/Events/run_01/unweighted_events.lhe' % samples[args.metype][0] 167 | ) 168 | sys.stdout.flush() 169 | -------------------------------------------------------------------------------- /src/Calorimeter.cxx: -------------------------------------------------------------------------------- 1 | 2 | #define _USE_MATH_DEFINES 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "fastjet/ClusterSequence.hh" 11 | 12 | #include "Calorimeter.h" 13 | //#include "CellBooster.h" 14 | 15 | using namespace std; 16 | using fastjet::PseudoJet; 17 | 18 | DetectorModel::RadialSmearing Calorimeter::m_smearer; 19 | 20 | void 21 | Calorimeter::init(unsigned int nEtaCells, unsigned int nPhiCells, 22 | bool phiGoesTo2Pi, double etaMax){ 23 | 24 | m_nEtaCells = nEtaCells; 25 | m_nPhiCells = nPhiCells; 26 | m_phiGoesTo2Pi = phiGoesTo2Pi; 27 | m_etaMax = etaMax; 28 | 29 | m_dEta = 2*etaMax/nEtaCells; 30 | m_dPhi = 2*M_PI/nPhiCells; 31 | 32 | m_energy = vector(nEtaCells*nPhiCells, 0.0); 33 | m_nInteractions = 0; 34 | 35 | m_smear = false; 36 | } 37 | 38 | double 39 | Calorimeter::rectify_phi(double phi, bool goes_to_2PI){ 40 | double ans = phi; 41 | double phiMin = goes_to_2PI ? 0 : -1 * M_PI; 42 | double phiMax = goes_to_2PI ? 2*M_PI : M_PI; 43 | 44 | ans += (ans < phiMin ? 2 * M_PI : 0); 45 | ans -= (ans > phiMax ? 2 * M_PI : 0); 46 | return ans; 47 | } 48 | 49 | double 50 | Calorimeter::etaCloseCell(double eta) const { 51 | //double deta = eta - -1*m_etaMax; 52 | double nCells = (eta - -1*m_etaMax)/m_dEta; 53 | int purportedCellIndex = floor(nCells); 54 | 55 | return -1 * m_etaMax + m_dEta * (0.5 + purportedCellIndex); 56 | } 57 | 58 | double 59 | Calorimeter::phiCloseCell(double phi) const { 60 | double phiMin = m_phiGoesTo2Pi ? 0 : -1 * M_PI; 61 | phi = rectify_phi(phi, m_phiGoesTo2Pi); 62 | 63 | double nCells = (phi - phiMin)/m_dPhi; 64 | int purportedCellIndex = floor(nCells); 65 | 66 | return phiMin + m_dPhi * (0.5 + purportedCellIndex); 67 | } 68 | 69 | double 70 | Calorimeter::etaFromIndex(unsigned int index) const { 71 | unsigned int ii = index / m_nPhiCells; 72 | double val = (ii+0.5)*2.0*m_etaMax/m_nEtaCells - m_etaMax; 73 | 74 | return val; 75 | } 76 | 77 | double 78 | Calorimeter::phiFromIndex(unsigned int index) const { 79 | unsigned int ii = index % m_nPhiCells; 80 | double val = (ii + 0.5) * 2.0*M_PI/m_nPhiCells; 81 | 82 | if (! m_phiGoesTo2Pi) val -= M_PI; 83 | return val; 84 | } 85 | 86 | int 87 | Calorimeter::makeIndex(double eta, double phi) const{ 88 | if (fabs(eta) > m_etaMax) return -1; 89 | 90 | double pcheck = rectify_phi(phi, m_phiGoesTo2Pi); 91 | if (fabs(pcheck - phi) > 0.1) return -1; 92 | 93 | return makeEtaIndex(eta)*m_nPhiCells + makePhiIndex(phi); 94 | } 95 | 96 | unsigned int 97 | Calorimeter::makeEtaIndex(double eta) const { 98 | unsigned int index = makeIndex(eta, -1*m_etaMax, m_etaMax, m_nEtaCells); 99 | return index; 100 | } 101 | 102 | unsigned int 103 | Calorimeter::makePhiIndex(double phi) const { 104 | unsigned int index; 105 | if(m_phiGoesTo2Pi) 106 | index = makeIndex(phi, 0, 2*M_PI, m_nPhiCells); 107 | else 108 | index = makeIndex(phi, -1*M_PI, 1*M_PI, m_nPhiCells); 109 | 110 | return index; 111 | } 112 | 113 | unsigned int 114 | Calorimeter::makeIndex(double val, double low, double high, double n) const { 115 | val = min(val, high); 116 | val = max(val, low); 117 | 118 | unsigned int index = (n*(val-low)/(high-low)); 119 | if (index == n) --index; 120 | return index; 121 | } 122 | 123 | void Calorimeter::push(const std::vector & jets) { 124 | std::vector::const_iterator jet = jets.begin(); 125 | std::vector::const_iterator jet_end = jets.end(); 126 | 127 | if (m_smear) { 128 | const std::vector & input = m_smearer.smear(jets); 129 | jet = input.begin(); 130 | jet_end = input.end(); 131 | } 132 | 133 | for (; jet != jet_end; ++jet) { 134 | if (m_phiGoesTo2Pi) 135 | addEnergy(jet->e(), jet->pseudorapidity(), jet->phi()); 136 | else 137 | addEnergy(jet->e(), jet->pseudorapidity(), jet->phi_std()); 138 | } 139 | } 140 | 141 | void Calorimeter::addEnergy(double e, double eta, double phi){ 142 | int ii = makeIndex(eta, phi); 143 | if (ii > -1) m_energy[ii] += e; 144 | } 145 | 146 | const Calorimeter 147 | Calorimeter::operator+(const Calorimeter &other) const { 148 | return Calorimeter(*this) += other; 149 | } 150 | 151 | Calorimeter& 152 | Calorimeter::operator+=(const Calorimeter &other){ 153 | //check all the indices are equal 154 | 155 | for(unsigned int ii=0; iim_energy)[ii] += other.m_energy[ii]; 157 | } 158 | this->m_nInteractions += other.m_nInteractions; 159 | 160 | return *this; 161 | } 162 | 163 | 164 | vector 165 | Calorimeter::getNonZeroCells(){ 166 | vector cells; 167 | float e, eta, phi; 168 | for (unsigned int ii=0; ii < m_nEtaCells * m_nPhiCells; ++ii){ 169 | 170 | e = m_energy[ii]; 171 | if (e<0.01) continue; 172 | 173 | eta = etaFromIndex(ii); 174 | phi = phiFromIndex(ii); 175 | PseudoJet pj(e*cos(phi)/cosh(eta), 176 | e*sin(phi)/cosh(eta), 177 | e*tanh(eta), 178 | e); 179 | pj.set_user_index(ii); 180 | cells.push_back(pj); 181 | } 182 | 183 | return cells; 184 | } 185 | 186 | double 187 | Calorimeter::get_cone_energy(double eta, double phi, double radius) const { 188 | double e_tot = 0; 189 | double maxEtaStep = ceil(radius/m_dEta - 0.1); 190 | double maxPhiStep = ceil(radius/m_dPhi - 0.1); 191 | double t_eta, t_phi; 192 | int cellIndex; 193 | 194 | //int howmany=0; 195 | for (int phiStep = -1*maxPhiStep; phiStep <= maxPhiStep; ++phiStep){ 196 | t_phi = phi + phiStep * m_dPhi; 197 | t_phi = rectify_phi(t_phi, m_phiGoesTo2Pi); 198 | 199 | for (int etaStep = -1*maxEtaStep; etaStep <= maxEtaStep; ++etaStep){ 200 | t_eta = eta + etaStep * m_dEta; 201 | 202 | cellIndex = makeIndex(t_eta, t_phi); 203 | e_tot += (cellIndex < 0 ? 0 : m_energy[cellIndex]); 204 | //if (cellIndex >=0) howmany++; 205 | } 206 | } 207 | 208 | //cout << "get_cone_energy took: " << howmany << endl; 209 | return e_tot; 210 | } 211 | 212 | string 213 | Calorimeter::toString() const { 214 | 215 | stringstream ss; 216 | ss << "["; 217 | 218 | for (int ii=0; ii whitelist, bool use_whitelist) const { 227 | double maxEtaStep = ceil(jet_radius/m_dEta - 0.1); 228 | double maxPhiStep = ceil(jet_radius/m_dPhi - 0.1); 229 | double t_eta, t_phi, ee; 230 | double rel_eta; 231 | double rel_phi; 232 | double origin_eta = get_eta_jet_offset(eta, jet_radius); 233 | double origin_phi = get_phi_jet_offset(phi, jet_radius); 234 | 235 | int cellIndex; 236 | unsigned int nCells = 0; 237 | 238 | 239 | stringstream ss, sFirst; 240 | ss << "'cells': ["; 241 | 242 | 243 | for (int phiStep = -1*maxPhiStep; phiStep <= maxPhiStep; ++phiStep){ 244 | for (int etaStep = -1*maxEtaStep; etaStep <= maxEtaStep; ++etaStep){ 245 | t_eta = eta + etaStep * m_dEta; 246 | t_phi = phi + phiStep * m_dPhi; 247 | t_phi = rectify_phi(t_phi, m_phiGoesTo2Pi); 248 | 249 | cellIndex = makeIndex(t_eta, t_phi); 250 | if (cellIndex < 0 || (use_whitelist && whitelist.count(cellIndex) == 0)) ee = 0; 251 | else ee = m_energy[cellIndex]; 252 | 253 | rel_eta = etaCloseCell(t_eta) - origin_eta; 254 | rel_phi = phiCloseCell(t_phi) - origin_phi; 255 | rel_phi += (rel_phi < -1 * m_dPhi ? 2*M_PI : 0); 256 | 257 | ss << "(" << ee/cosh(etaCloseCell(t_eta)); 258 | ss << ", " << rel_eta; 259 | ss << ", " << rel_phi; 260 | ss << "),"; 261 | ++nCells; 262 | } 263 | } 264 | 265 | ss << "], 'n_cells': '" << nCells << "',"; 266 | ss << "'jet_offset': (" << origin_eta << ", " << origin_phi; 267 | ss << "), "; 268 | return ss.str(); 269 | } 270 | -------------------------------------------------------------------------------- /src/pythiaJets.cxx: -------------------------------------------------------------------------------- 1 | //std things 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | //#include 8 | 9 | //things josh installed 10 | #include "boost/program_options.hpp" 11 | 12 | //physics things josh installed 13 | #include "Pythia.h" 14 | #include "JetMatching.h" 15 | #include "CombineMatchingInput.h" 16 | #include "HepMCInterface.h" 17 | //#include "CellBooster.h" 18 | 19 | //physics things josh wrote 20 | #include "JetAnalysis.h" 21 | 22 | #define HAS_NS_TIME 23 | #define _USE_MATH_DEFINES 24 | 25 | using std::cout; 26 | using std::endl; 27 | using std::string; 28 | using std::map; 29 | namespace po = boost::program_options; 30 | 31 | int getSeed(int optSeed){ 32 | if (optSeed > -1) return optSeed; 33 | 34 | int timeSeed = time(NULL); 35 | 36 | #ifdef HAS_NS_TIME 37 | { 38 | timespec tp; 39 | if ( 0 == clock_gettime(CLOCK_REALTIME, &tp)) timeSeed = tp.tv_nsec; 40 | } 41 | #endif 42 | 43 | //http://arxiv.org/abs/1005.4117 supposed to keep collisions down to 44 | //My seed is strong... 45 | return abs(((timeSeed*181)*((getpid()-83)*359))%104729); 46 | } 47 | 48 | 49 | void setLeptonDecays(const char MATRIX_ELEMENT, const int LEP_CHARGE, Pythia8::Pythia &pythia){ 50 | 51 | if( !(MATRIX_ELEMENT=='w' || MATRIX_ELEMENT=='t' || MATRIX_ELEMENT=='v') ) 52 | return; 53 | 54 | 55 | if(LEP_CHARGE==0) 56 | { 57 | pythia.readString("24:onIfAny = 13"); //dilepton 58 | 59 | if(MATRIX_ELEMENT=='w') cout << "Turning on dilepton W^+ W^- --> l^+ + nu + l^- + nu production" << endl; 60 | if(MATRIX_ELEMENT=='t') cout << "Turning on dilepton t tbar --> l^+ + nu + l^- + nu b + b production" << endl; 61 | if(MATRIX_ELEMENT=='v') cout << "Turning on W(->l nu)+jet production" << endl; 62 | } 63 | else if(LEP_CHARGE==1) 64 | { 65 | pythia.readString("24:onPosIfAny = 13"); //W^+ decays leptonically to electron or muon 66 | if(MATRIX_ELEMENT=='t' || MATRIX_ELEMENT=='w') 67 | pythia.readString("24:onNegIfAny = 1 2 3 4 5");// W^- decays hadronically 68 | 69 | if(MATRIX_ELEMENT=='w') cout << "Turning on semi-leptonic W^+ W^- -> l^+ + nu + j+j production" << endl; 70 | if(MATRIX_ELEMENT=='t') cout << "Turning on semi-leptonic t tbar -> l^+ + nu + b + b + j+j production" << endl; 71 | if(MATRIX_ELEMENT=='v') cout << "Turning on W^-(->l^+ nu)+jet production" << endl; 72 | } 73 | else if(LEP_CHARGE==-1) 74 | { 75 | pythia.readString("24:onNegIfAny = 13"); //W^- decays leptonically to electron or muon 76 | if(MATRIX_ELEMENT=='t' || MATRIX_ELEMENT=='w') 77 | pythia.readString("24:onPosIfAny = 1 2 3 4 5");// W^+ decays hadronically 78 | 79 | 80 | if(MATRIX_ELEMENT=='w') cout << "Turning on semi-leptonic W^+ W^- -> l^- + nu + j+j production" << endl; 81 | if(MATRIX_ELEMENT=='t') cout << "Turning on semi-leptonic t tbar -> l^- + nu + b + b + j+j production" << endl; 82 | if(MATRIX_ELEMENT=='v') cout << "Turning on W^-(->l^- nu)+jet production" << endl; 83 | } 84 | else 85 | { 86 | pythia.readString("24:onIfAny = 1 2 3 4 5"); //all hadronic 87 | 88 | if(MATRIX_ELEMENT=='w') cout << "Turning on W^+ W^- -> all hadronic production" << endl; 89 | if(MATRIX_ELEMENT=='t') cout << "Turning on t tbar -> all hadronic production" << endl; 90 | if(MATRIX_ELEMENT=='v') cout << "Turning on W(->hadronic)+jet production" << endl; 91 | } 92 | 93 | return; 94 | } 95 | 96 | int main(int argc, char* argv[]) { 97 | cout << "Called as: "; 98 | for(int ii=0; ii(&LHEFile)->default_value("") 125 | , "Location of an LHE file, over-rides all other Pythia event generation options") 126 | ("matching", "Turn on jet matching (e.g. for Madgraph LHE input)") 127 | ("metype", po::value(&optME)->default_value('g') 128 | , "g,q,l,b,c,v,t,W") 129 | ("lepcharge", po::value (&optLepQ) ->default_value(1) 130 | , "Charge of lepton desired in final state, only for ME ={v, t, W}. 1=l^+, -1=l^-, 0= All lepton flavors, any other value = no lepton (all hadronic),") 131 | ("seed", po::value(&optSeed) ->default_value(-1) 132 | , "Random seed. The default, -1, causes the application to " 133 | "choose one from the ns time as pid") 134 | ("savemaxnjets", po::value(&optSaveMaxNJets) ->default_value(-1) 135 | , "Max number of jets to save. Default, -1, saves all jets (which satisfy other selectons)") 136 | ("nevents", po::value (&optNEvents) ->default_value(1) 137 | , "# Events to generate") 138 | ("cellv", po::value(&optCellV) ->default_value(1) 139 | , "Control how many and which cells to output. 0 shows no cells, 1 (default) shows only those that survive trimming and 2 shows all cells in a jet.") 140 | ("meminpt" , po::value(&optMEMinPt) ->default_value(50.0) 141 | , "Pythia PTHatMin (GeV)") 142 | ("memaxpt" , po::value(&optMEMaxPt) ->default_value(20000) 143 | , "Pythia PTHatMax (GeV)") 144 | ("trimjet", po::value (&optTrimJet) ->default_value(1) 145 | , "To run trimming or not. Any value other than 1 (default) disables trimming.") 146 | ("jetminpt" , po::value(&optJetMinPt) ->default_value(25.0) 147 | , "Jet PTMin (GeV)") 148 | ("jetmaxpt" , po::value(&optJetMaxPt) ->default_value(99999.0) 149 | , "Jet PTMax (GeV)") 150 | ("jetminm" , po::value(&optJetMinM) ->default_value(0) 151 | , "Jet Min Mass (GeV)") 152 | ("jetmaxm" , po::value(&optJetMaxM) ->default_value(20000) 153 | , "Jet Max Mass (GeV)") 154 | ("rad" , po::value(&optJetRadius) ->default_value(0.4) 155 | , "Jet Finder Radius") 156 | ("mu" , po::value(&optMu) ->default_value(0.0) 157 | , "Average Int./Cross") 158 | ("smear" , "Turn on radial energy smearing") 159 | ("wtagger", "Turn on MVA Tagger output") 160 | ("disablempi", "Dislable Multiple Parton Interactions") 161 | ("n_B" , po::value(&optNB) ->default_value(-1) 162 | , "Exactl number of b-hadrons per-jet (-1 for no cut)") 163 | ; 164 | po::variables_map vm; 165 | po::store(po::parse_command_line(argc, argv, desc), vm); 166 | po::notify(vm); 167 | 168 | if (vm.count("help")>0){ 169 | cout << desc << "\n"; 170 | return 1; 171 | } 172 | 173 | const char MATRIX_ELEMENT = tolower(optME); 174 | const int LEP_CHARGE = optLepQ; 175 | const int N_EVENTS = optNEvents; 176 | const int R_SEED = getSeed(optSeed); 177 | const int ME_PT_MIN = optMEMinPt; 178 | const int ME_PT_MAX = optMEMaxPt; 179 | const int DO_TRIMMING = optTrimJet; 180 | const float MU = optMu; 181 | 182 | // { 183 | // CellBooster cb(R_SEED); 184 | // cb.split_cell(100, 10, .1, 0.2, 0, 0.1); 185 | // } 186 | // return 1; 187 | 188 | std::stringstream ss; 189 | Pythia8::Pythia pythia; 190 | 191 | pythia.readString("Random:setSeed = on"); 192 | ss.clear(); ss.str(""); 193 | ss << "Random:seed = " << R_SEED; 194 | cout << ss.str() << endl; 195 | pythia.readString(ss.str()); 196 | 197 | if (LHEFile == "") { 198 | optME='?'; 199 | 200 | pythia.readString("HardQCD:all = off"); 201 | 202 | if (MATRIX_ELEMENT == 'g'){ 203 | pythia.readString("HardQCD:gg2gg = on"); 204 | pythia.readString("HardQCD:qqbar2gg = on"); 205 | cout << "Turning on gg production" << endl; 206 | } else if (MATRIX_ELEMENT == 'q'){ 207 | pythia.readString("HardQCD:gg2qqbar = on"); 208 | pythia.readString("HardQCD:qq2qq = on"); 209 | cout << "Turning on qq production" << endl; 210 | } else if (MATRIX_ELEMENT == 'l') { 211 | pythia.readString("HardQCD:gg2gg = on"); 212 | pythia.readString("HardQCD:gg2qqbar = on"); 213 | pythia.readString("HardQCD:qg2qg = on"); 214 | pythia.readString("HardQCD:qq2qq = on"); 215 | pythia.readString("HardQCD:qqbar2gg = on"); 216 | pythia.readString("HardQCD:qqbar2gg = on"); 217 | pythia.readString("HardQCD:qqbar2qqbarNew = on"); 218 | } else if (MATRIX_ELEMENT == 'c') { 219 | pythia.readString("HardQCD:gg2ccbar = on"); 220 | pythia.readString("HardQCD:qqbar2ccbar = on"); 221 | } else if (MATRIX_ELEMENT == 'b') { 222 | pythia.readString("HardQCD:gg2bbbar = on"); 223 | pythia.readString("HardQCD:qqbar2bbbar = on"); 224 | } else if (MATRIX_ELEMENT == 'v'){ 225 | pythia.readString("WeakBosonAndParton:qqbar2Wg = on"); 226 | pythia.readString("WeakBosonAndParton:qg2Wq = on"); 227 | pythia.readString("24:onMode = off"); 228 | cout << "When ME = " << MATRIX_ELEMENT << " lepton charge forced to 0" << endl; 229 | setLeptonDecays(MATRIX_ELEMENT, 0, pythia); 230 | 231 | } else if (MATRIX_ELEMENT == 't'){ 232 | pythia.readString("Top:gg2ttbar = on"); 233 | pythia.readString("Top:qqbar2ttbar = on"); 234 | //pythia.readString("Top:ffbar2ttbar = on"); 235 | //pythia.readString("Top:gmgm2ttbar = on"); 236 | pythia.readString("24:onMode = off"); 237 | setLeptonDecays(MATRIX_ELEMENT, LEP_CHARGE, pythia); 238 | 239 | } else if (MATRIX_ELEMENT == 'w'){ 240 | pythia.readString("WeakDoubleBoson:ffbar2WW = on"); 241 | pythia.readString("24:onMode = off"); 242 | setLeptonDecays(MATRIX_ELEMENT, LEP_CHARGE, pythia); 243 | 244 | } else { 245 | cout << "Unknown Matrix Element type " << MATRIX_ELEMENT << endl; 246 | cout << "Try q or g or v or t or W" << endl; 247 | return -1; 248 | } 249 | 250 | //Only applicable to 2->2 processes, ie use WW 251 | ss.clear(); ss.str(""); 252 | ss << "PhaseSpace:pTHatMin = " << ME_PT_MIN; 253 | cout << ss.str() << endl; 254 | pythia.readString(ss.str()); 255 | 256 | ss.clear(); ss.str(""); 257 | ss << "PhaseSpace:pTHatMax = " << ME_PT_MAX; 258 | cout << ss.str() << endl; 259 | pythia.readString(ss.str()); 260 | 261 | if (vm.count("disablempi")>0) pythia.readString("PartonLevel:MI = off"); 262 | pythia.init(2212, 2212, 8000); 263 | 264 | } else { 265 | if (vm.count("matching") > 0) { 266 | cout << "Set matching parameters" << endl; 267 | pythia.readString("JetMatching:merge = on"); 268 | pythia.readString("JetMatching:setMad = off:"); 269 | pythia.readString("JetMatching:scheme = 1"); 270 | pythia.readString("JetMatching:qCut = 30"); 271 | pythia.readString("JetMatching:nQmatch = 5"); 272 | pythia.readString("JetMatching:clFact = 1"); 273 | 274 | CombineMatchingInput combined; 275 | UserHooks* matching = combined.getHook(pythia); 276 | if (!matching) return 1; 277 | pythia.setUserHooksPtr(matching); 278 | } 279 | pythia.init(LHEFile.c_str()); 280 | } 281 | 282 | pythia.settings.listAll(); 283 | 284 | 285 | JetAnalysis jet_analysis(optSaveMaxNJets, 286 | DO_TRIMMING, 287 | optJetMinPt, 288 | optJetMaxPt, 289 | optJetMinM, 290 | optJetMaxM, 291 | optJetRadius, 292 | optNB, 293 | MU, 294 | R_SEED, 295 | (vm.count("smear")>0 ? true : false), 296 | (vm.count("wtagger")>0 ? true : false), 297 | optCellV 298 | ); 299 | 300 | map props; 301 | props["source"] = "Pythia8"; 302 | ss.clear(); ss.str(""); 303 | ss << MATRIX_ELEMENT; 304 | props["ME"] = ss.str(); 305 | ss.clear(); ss.str(""); 306 | ss << R_SEED; 307 | props["seed"] = ss.str(); 308 | 309 | HepMC::GenEvent *gevt = new HepMC::GenEvent(); 310 | 311 | 312 | for (int iEvent = 0; iEvent < N_EVENTS; ++iEvent) { 313 | if (!pythia.next()) continue; 314 | //pythia.event.list(); 315 | 316 | ss.clear(); ss.str(""); 317 | ss << iEvent; 318 | props["eventNumber"] = ss.str(); 319 | 320 | delete gevt; 321 | gevt = new HepMC::GenEvent(); 322 | 323 | HepMC::I_Pythia8().fill_next_event(pythia, gevt); 324 | jet_analysis.analyze(gevt, props); 325 | continue; 326 | 327 | } 328 | pythia.stat(); 329 | return 0; 330 | } 331 | -------------------------------------------------------------------------------- /text2bin.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | __author__ = 'Josh Cogan' 4 | 5 | import os 6 | import sys 7 | import time 8 | import InputCleaner as ic 9 | #G{'ME': 'g', 'e': '62.3739', 'eta': '-0.519661', 'eventNumber': '0', 'm': '11.2668', 'nParts': '16', 'npv': '1', 'pdgIDHardParton': '21', 'phi': '2.17741', 'pt': '53.9043', 'radius': '0.4', 'rap': '-0.509537', 'seed': '10105', 'source': 'Pythia8', 'subjetRadius': '0.3', 'cells': [(0, 4.16334e-17, 8.32667e-17),(0, 0.1, 8.32667e-17),(0, 0.2, 8.32667e-17),(0, 0.3, 8.32667e-17),(0, 0.4, 8.32667e-17),(0, 0.5, 8.32667e-17),(0, 0.6, 8.32667e-17),(0, 0.7, 8.32667e-17),(0, 0.8, 8.32667e-17),(0, 4.16334e-17, 0.0997331),(0, 0.1, 0.0997331),(2.89078, 0.2, 0.0997331),(0, 0.3, 0.0997331),(0, 0.4, 0.0997331),(0, 0.5, 0.0997331),(0, 0.6, 0.0997331),(0, 0.7, 0.0997331),(0, 0.8, 0.0997331),(0, 4.16334e-17, 0.199466),(0, 0.1, 0.199466),(0, 0.2, 0.199466),(2.53236, 0.3, 0.199466),(1.06125, 0.4, 0.199466),(0, 0.5, 0.199466),(0, 0.6, 0.199466),(0, 0.7, 0.199466),(0, 0.8, 0.199466),(0, 4.16334e-17, 0.299199),(0, 0.1, 0.299199),(0.24269, 0.2, 0.299199),(18.4752, 0.3, 0.299199),(5.57112, 0.4, 0.299199),(0.480723, 0.5, 0.299199),(0, 0.6, 0.299199),(3.49651, 0.7, 0.299199),(2.14862, 0.8, 0.299199),(0, 4.16334e-17, 0.398932),(0, 0.1, 0.398932),(1.48241, 0.2, 0.398932),(0, 0.3, 0.398932),(0, 0.4, 0.398932),(0, 0.5, 0.398932),(0, 0.6, 0.398932),(0, 0.7, 0.398932),(0, 0.8, 0.398932),(0, 4.16334e-17, 0.498666),(0, 0.1, 0.498666),(0, 0.2, 0.498666),(0, 0.3, 0.498666),(1.24219, 0.4, 0.498666),(13.8829, 0.5, 0.498666),(0, 0.6, 0.498666),(1.23478, 0.7, 0.498666),(0, 0.8, 0.498666),(0, 4.16334e-17, 0.598399),(0, 0.1, 0.598399),(0, 0.2, 0.598399),(0, 0.3, 0.598399),(0, 0.4, 0.598399),(2.70018, 0.5, 0.598399),(4.10979, 0.6, 0.598399),(0, 0.7, 0.598399),(0, 0.8, 0.598399),(0, 4.16334e-17, 0.698132),(0, 0.1, 0.698132),(0, 0.2, 0.698132),(0, 0.3, 0.698132),(0, 0.4, 0.698132),(0.822497, 0.5, 0.698132),(0, 0.6, 0.698132),(0, 0.7, 0.698132),(0, 0.8, 0.698132),(0, 4.16334e-17, 0.797865),(0, 0.1, 0.797865),(0, 0.2, 0.797865),(0, 0.3, 0.797865),(0, 0.4, 0.797865),(0, 0.5, 0.797865),(0, 0.6, 0.797865),(0, 0.7, 0.797865),(0, 0.8, 0.797865),], 'n_cells': '81','jet_offset': (-0.95, 1.7952), 'subjets': [(26.9217, -0.641016, 2.07111),(21.8911, -0.427662, 2.32936),],'rel_subjets': [(26.9217, 0.308984, 0.275916),(21.8911, 0.522338, 0.534161),], 'pu_energies': [], 'pu_energy': 0} 10 | 11 | _stringToInts = {'source': {'Pythia8':0, 'Herwig':1, 'HepMC':1}, 12 | 'ME' : {'q': 1, 'g':21, 'w':24, 'v':2, 'c':4, 'b': 5, 't':6, 'h': 25}, 13 | } 14 | 15 | _indexToNames = { 16 | #'parts' : [('pdgId','i4'),('E' ,'f8'),('cosT','f8'),('phi','f8')], 17 | 'cells' : [('E' ,'f8'), ('eta', 'f8') , ('phi','f8')], 18 | 'subjets' : [('E' ,'f8'), ('eta', 'f8') , ('phi','f8')], 19 | 'rel_subjets' : [('E' ,'f8'), ('eta', 'f8') , ('phi','f8')], 20 | } 21 | 22 | _integer_whitelist = set(('pdgIDHardParton', 'eventNumber', 'seed', 'nParts', 'npv')) 23 | 24 | def handleCLI(): 25 | from optparse import OptionParser 26 | 27 | usage = '%prog [options] [-o] outputFile input1 input2 ...' 28 | 29 | pp = OptionParser(usage=usage) 30 | pp.add_option('-f', '--format', dest='format', default=None, 31 | help='Set the output format to either root or numpy.' 32 | ' If not set, the ouput is a ROOT file if it ends in' 33 | ' .root (case sensitive).') 34 | 35 | pp.add_option('-o', '--output', dest='output', default=None, 36 | help='Set the output filename. If not specified then' 37 | ' the first filename after the options is used.') 38 | pp.add_option('-e', '--end', dest='end', type=int, default=-1, 39 | help='Specify maximum number of rows to attempt to process' 40 | ' -1 processes all rows available') 41 | 42 | pp.add_option('-s', '--search', dest='search', default=None, 43 | help='Regex with possible grouping. Each line in' 44 | ' the input text must match this search before it gets' 45 | ' converted. If there are groups in this regex, then' 46 | ' they may be used by the --repl option. For' 47 | ' example, some files may require -s \'r"^#G(.*)$"\'' 48 | ' -r \'r"\\1"\'.') 49 | 50 | pp.add_option('-r', '--repl', dest='repl', default=None, 51 | help='Replacement regex with possible grouping. ' 52 | ' See --search') 53 | 54 | opts, args = pp.parse_args() 55 | 56 | if opts.output is None: 57 | try: 58 | opts.output = args.pop(0) 59 | except IndexError: 60 | print 'Please specify an output file!' 61 | pp.print_help() 62 | sys.exit(1) 63 | 64 | if len(args) == 0: 65 | print 'Please specify one or more input files!' 66 | pp.print_help() 67 | sys.exit(1) 68 | 69 | if opts.format is None: 70 | print opts.output 71 | if '.root' == os.path.splitext(opts.output)[1]: 72 | opts.format = 'root' 73 | else: 74 | opts.format = 'npy' 75 | 76 | return opts, args 77 | 78 | def makeListOfVariables(record): 79 | lov = [] 80 | #usedNames = set() 81 | #cannot trust InputCleaner to get 1.0 vs 1 right. 82 | #see makeListOfStructVariables 83 | print 'I WILL SCREW UP INT VS FLOAT' 84 | for kk, vv in record.iteritems(): 85 | if isinstance(vv, list) or isinstance(vv, tuple): 86 | try: 87 | nested = isinstance(vv[0], list) or isinstance(vv[0], tuple) 88 | except IndexError: 89 | nested = False 90 | 91 | if 'n_%s' % kk not in record.keys(): 92 | lov.append(['n_%s' % kk, 'I']) 93 | 94 | if nested: 95 | #this should RIGHTLY break if kk not in _indexToNames!! 96 | for index, nameAndType in enumerate(_indexToNames[kk]): 97 | name, tt = nameAndType 98 | lov.append([kk + '_' + name, 'D:' if tt[0]=='f' else 'I:']) 99 | else: 100 | try: 101 | tt = 'I' if isinstance(vv[0], int) else 'D' 102 | except IndexError: 103 | tt = 'D' 104 | lov.append([kk, tt+':']) 105 | 106 | elif isinstance(vv, str ): lov.append([kk, 'I']) 107 | elif isinstance(vv, int ): lov.append([kk, 'I']) 108 | elif isinstance(vv, float): lov.append([kk, 'D']) 109 | else: 110 | print "I don't know how to parse key value pair: %s, %s" % (kk, vv) 111 | sys.exit(1) 112 | 113 | return lov 114 | 115 | def makeListOfStructVariables(record): 116 | jetType = [] 117 | #don't be so "smart" about type intuition 118 | easymap = {str: 'i4', int: 'f8', float: 'f8'} 119 | 120 | for kk, vv in record.iteritems(): 121 | if 'n_' == kk[:2] or kk in _integer_whitelist: 122 | #don't be so "smart" about type intuition 123 | jetType.append((kk, int)) 124 | continue 125 | 126 | try: 127 | jetType.append((kk, easymap[type(vv)])) 128 | continue 129 | except KeyError: 130 | pass 131 | 132 | #okay vv is list or tuple 133 | if kk in _indexToNames: 134 | ##this should return 10 for subjets 135 | ##and the full length for cells 136 | nelems = max(10, len(vv)) 137 | jetType.append((kk, _indexToNames[kk], nelems)) 138 | if 'n_%s' % kk not in record.keys(): 139 | jetType.append(('n_%s' % kk, 'i4')) 140 | continue 141 | 142 | if 'offset' in kk: 143 | jetType.append((kk, 'f8', 2)) 144 | else: #puenergies 145 | jetType.append((kk, 'f8', 100)) 146 | if 'n_%s' % kk not in record.keys(): 147 | jetType.append(('n_%s' % kk, 'i4')) 148 | 149 | 150 | return jetType 151 | 152 | def makeRootFile(fname, incoming, max_elems): 153 | first = [rr for rr in incoming.getGen(1)][0] 154 | listOfVars = makeListOfVariables(first) 155 | print 'Will produce a ROOT file with these fields [' 156 | for name, cType in sorted(listOfVars, key=lambda li: li[0]): 157 | print ' %s, %s' % (name.ljust(30), cType) 158 | print ']' 159 | 160 | import ROOT as rt 161 | fOut = rt.TFile(fname, 'recreate') 162 | tree_out = rt.TTree("physics", "physics") 163 | 164 | import pyrootmagic as prm 165 | vs, varsWithInTrees = prm.getAndLoadStruct(listOfVars, None, force_recompile=True) 166 | print 'pyroot struct written, compiled and loaded' 167 | ### Struct can't be garbage collected before tree 168 | ### http://root.cern.ch/phpBB3/viewtopic.php?f=14&t=8585 169 | tree_out._vs = vs 170 | prm.mapVariablesToBranches(vs, tree_out, listOfVars) 171 | 172 | printPoint = 0.1 173 | nRecord = incoming.size() 174 | 175 | print "BLARGH still need to handle n_subjets with subjets autogenerated??" 176 | print "BLARGH still need to handle n_subjets with subjets autogenerated??" 177 | print "BLARGH still need to handle n_subjets with subjets autogenerated??" 178 | for iRecord, record in enumerate(incoming.getGen(max_elems)): 179 | if iRecord % (nRecord * printPoint) == 0: 180 | print 'Working on the %d%%th event' % (100*iRecord/nRecord) 181 | prm.clearStruct(vs) 182 | for kk, vv in record.iteritems(): 183 | if kk in _indexToNames: # its the pdgid/pt/eta/phi quadruplet 184 | if 'n_%s' % kk not in record.keys(): 185 | pass 186 | #setattr(vs, 'n_%s' % kk, len(record[kk])) 187 | for vIndex, nameAndType in enumerate(_indexToNames[kk]): 188 | name = nameAndType[0] 189 | vec = getattr(vs, kk+'_'+name) 190 | for partIndex in range(len(record[kk])): 191 | vec.push_back(vv[partIndex][vIndex]) 192 | 193 | elif kk in _stringToInts: 194 | setattr(vs, kk, _stringToInts[kk][vv]) 195 | else: 196 | setattr(vs, kk, vv) 197 | 198 | tree_out.Fill() 199 | 200 | fOut.Write() 201 | fOut.Close() 202 | 203 | def makeNumpyArray(inputcleaner, max_elems): 204 | import numpy as np 205 | 206 | first = [rr for rr in inputcleaner.getGen(1)][0] 207 | jetType = makeListOfStructVariables(first) 208 | #print jetType 209 | 210 | print "This 25000 is a hack for MemoryError" 211 | ra = np.zeros(min(inputcleaner.size(), max_elems if max_elems >= 0 else 25000), dtype=jetType) 212 | for iRec, rec in enumerate(inputcleaner.getGen(max_elems)): 213 | if iRec >= 25000: 214 | print "Limiting to 25000 jets per file" 215 | break 216 | for kk, vv in rec.iteritems(): 217 | if kk in _indexToNames: 218 | namelist = [li[0] for li in _indexToNames[kk]] 219 | npvv = np.array(vv) 220 | for iname, name in enumerate(namelist): 221 | ra[iRec][kk][name][:len(vv)] = npvv[:,iname] 222 | ra[iRec]['n_%s' % kk] = len(vv) 223 | continue 224 | 225 | # print npvv 226 | # print npvv.shape 227 | # print ra[iRec][kk] 228 | # print ra[iRec][kk]['E'] 229 | # sys.exit(0) 230 | # for ielem, elem in enumerate(vv): 231 | # ra[iRec][kk][ielem] 232 | #dType = _indexToNames[kk] 233 | #sublist = np.zeros(len(rec[kk]), dtype=dType) 234 | #for isubsublist, subsublist in enumerate(vv): 235 | # for iElem, elem in enumerate(subsublist): 236 | # sublist[isubsublist][_indexToNames[kk][iElem][0]] = elem 237 | #ra[iRec][kk] = sublist 238 | #continue 239 | 240 | if kk in _stringToInts: 241 | ra[iRec][kk] = _stringToInts[kk][vv] 242 | continue 243 | 244 | if isinstance(vv, tuple) or isinstance(vv, list): 245 | ra[iRec][kk][:len(vv)] = np.array(vv) 246 | continue 247 | 248 | ra[iRec][kk] = vv 249 | 250 | ra = ra[:iRec+1] 251 | return ra 252 | 253 | def makeNumpyFile(outFile, inputcleaner, max_elems): 254 | import numpy as np 255 | 256 | ra = makeNumpyArray(inputcleaner, max_elems) 257 | fhandle = open(outFile, 'w') 258 | np.save(fhandle, ra) 259 | fhandle.close() 260 | 261 | if __name__ == '__main__': 262 | opts, args = handleCLI() 263 | 264 | incoming = ic.InputCleanerGen(args, sys.stdin, search=opts.search, 265 | repl =opts.repl) 266 | 267 | if opts.format == 'root': 268 | makeRootFile (opts.output, incoming, opts.end) 269 | else: 270 | makeNumpyFile(opts.output, incoming, opts.end) 271 | 272 | ### Testing suite just in case 273 | # import numpy as np 274 | # ra = np.load(open(opts.output)) 275 | # print 276 | # print ra.shape 277 | # print ra 278 | # print ra['npv'], ra['e'] 279 | # print "ra['rel_subjets'][0]['E']" 280 | # print ra['rel_subjets'][0]['E'] 281 | # print "ra[0]['rel_subjets']['E']" 282 | # print ra[0]['rel_subjets']['E'] 283 | -------------------------------------------------------------------------------- /src/JetAnalysis.cxx: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | //physics things josh found 6 | #include "HepMC/GenEvent.h" 7 | 8 | //physics things josh installed 9 | #include "fastjet/ClusterSequence.hh" 10 | #include "fastjet/tools/Filter.hh" 11 | #include "Nsubjettiness/Nsubjettiness.hh" 12 | 13 | //physics things josh wrote 14 | #include "JetAnalysis.h" 15 | #include "Calorimeter.h" 16 | #include "PythiaPileUp.h" 17 | #include "ExtendableJet.h" 18 | 19 | //Harvard MVA Tagger 20 | #include "wtag.h" 21 | 22 | void Cuts::passed(std::string cut_name) { 23 | if (cut_name != "" && m_counter >= m_name.size()) { 24 | m_name.push_back(cut_name); 25 | m_passed.push_back(0); 26 | } 27 | if (cut_name == "" || m_name[m_counter] == cut_name) { 28 | m_passed[m_counter++] += 1; 29 | } 30 | } 31 | 32 | void Cuts::print() { 33 | cout << "Cut Summary: " << endl; 34 | for (int i = 0, iEnd = m_passed.size(); i < iEnd; ++i) { 35 | cout << " " << m_name[i] << ": " << m_passed[i] << endl; 36 | } 37 | } 38 | 39 | void 40 | JetAnalysis::init(int saveMaxNJets, int trimJets, float jetMinPt, float jetMaxPt, 41 | float jetMinM, float jetMaxM, 42 | float jetRadius, int nB, int mu, int puSeed, bool doSmear, bool doWTagger, int cellV){ 43 | 44 | m_saveMaxNJets = saveMaxNJets; 45 | m_trimJets = trimJets; 46 | m_jetMinPt = jetMinPt; 47 | m_jetMaxPt = jetMaxPt; 48 | m_jetMinM = jetMinM; 49 | m_jetMaxM = jetMaxM; 50 | m_jetRadius = jetRadius; 51 | m_nB = nB; 52 | m_mu = mu; 53 | m_doSmear = doSmear; 54 | m_doWTagger = doWTagger; 55 | m_cellV = cellV; 56 | 57 | m_minDR = std::min(2.5*m_jetRadius, 1.5); 58 | m_trimRadius = 0.3; 59 | 60 | //recall this is needed for BDRS MassDropTagger 61 | m_primaryDef = fastjet::JetDefinition(fastjet::cambridge_algorithm, m_jetRadius); 62 | m_trimDef = fastjet::JetDefinition(fastjet::kt_algorithm, m_trimRadius); 63 | m_selPtMin = fastjet::SelectorPtMin(m_jetMinPt); 64 | m_selPtMax = fastjet::SelectorPtMax(m_jetMaxPt); 65 | m_basePtMin= fastjet::SelectorPtMin(25); 66 | m_selDR = fastjet::operator!(fastjet::SelectorDoughnut(.00001, m_minDR)); 67 | m_selEta = fastjet::SelectorAbsRapRange(0, 2.5); 68 | 69 | std::stringstream ss; 70 | ss << m_jetRadius << "_" << m_jetMinPt << "_" << m_jetMaxPt << "_" << m_minDR ; 71 | m_desc = ss.str(); 72 | 73 | m_hs_calo = Calorimeter(50, 63, false, 2.5); 74 | m_pug = new PythiaPileUpGenerator(m_mu, m_hs_calo, puSeed); 75 | m_hs_calo.setSmear(m_doSmear); 76 | 77 | m_wtagEffs.clear(); 78 | m_wtagEffs.push_back(10); 79 | m_wtagEffs.push_back(15); 80 | m_wtagEffs.push_back(20); 81 | m_wtagEffs.push_back(25); 82 | m_wtagEffs.push_back(30); 83 | m_wtagEffs.push_back(35); 84 | m_wtagEffs.push_back(40); 85 | m_wtagEffs.push_back(45); 86 | m_wtagEffs.push_back(50); 87 | m_wtagEffs.push_back(55); 88 | m_wtagEffs.push_back(60); 89 | m_wtagEffs.push_back(65); 90 | m_wtagEffs.push_back(70); 91 | m_wtagEffs.push_back(75); 92 | m_wtagEffs.push_back(80); 93 | m_wtagEffs.push_back(85); 94 | m_wtagEffs.push_back(90); 95 | m_wtagEffs.push_back(95); 96 | 97 | for (int ii=1; ii<=5; ++ii){ 98 | m_nSubCalcs[ii] = new fastjet::contrib::Nsubjettiness::Nsubjettiness( 99 | ii, 100 | fastjet::contrib::Njettiness::onepass_kt_axes, 101 | 1, 102 | m_jetRadius, 103 | 10000.0 104 | ); 105 | } 106 | } 107 | 108 | JetAnalysis::~JetAnalysis() { 109 | delete m_pug; 110 | m_pug = 0; 111 | 112 | std::map::iterator it; 113 | for (it=m_nSubCalcs.begin(); it!=m_nSubCalcs.end(); ++it) delete it->second; 114 | 115 | m_jetCuts.print(); 116 | } 117 | 118 | bool 119 | JetAnalysis::is_qhadron(int qid, int pid){ 120 | //working from http://pdg.lbl.gov/2002/montecarlorpp.pdf 121 | //if meson either 10 or 100's digit need to be 5 122 | //but no top quark bound state, so b always heaviest 123 | //--> hundrends digit 124 | //if baryon then 5 in thousands digit! 125 | qid = abs(qid); 126 | pid = abs(pid); 127 | assert(qid > 0 && qid < 7); 128 | return (((pid/100)%10)==qid || ((pid/1000)%10)==qid); 129 | } 130 | 131 | 132 | bool 133 | JetAnalysis::is_final_qhadron(int qid, HepMC::GenParticle *gp){ 134 | //is b_hadron with no b's in children 135 | 136 | if (! is_qhadron(qid, gp->pdg_id())) return false; 137 | //cout << "#BPasses bhadron with id: " << abs(gp->pdg_id()) << endl; 138 | 139 | HepMC::GenVertex *end = gp->end_vertex(); 140 | HepMC::GenVertex::particles_out_const_iterator it; 141 | for(it =end->particles_out_const_begin(); 142 | it!=end->particles_out_const_end (); ++it){ 143 | 144 | if (is_qhadron(qid, (*it)->pdg_id())) return false; 145 | 146 | } 147 | return true; 148 | } 149 | 150 | //I'm gonna smack the snot out of a hepmc developer. 151 | //Who creates a particle class and disallows the ability to store charge 152 | //Do you *really* think that one last int...SHORT event is gonna break 153 | //the bank? 154 | //But WHATEVER i just redid the math myself thank you. 155 | // only works for longer lived particles, not checked on 156 | // susy/technicolor/etc 157 | bool 158 | JetAnalysis::is_charged(int pdg_id){ 159 | int id = abs(pdg_id); 160 | if ( 161 | id == 12 || 162 | id == 14 || 163 | id == 16 || 164 | id == 22 165 | ) return false; 166 | 167 | int q1 = id/10 % 10; 168 | int q2 = id/100 % 10; 169 | int q3 = id/1000 % 10; 170 | 171 | int charge = (q1 % 2 == 0? 2: -1); 172 | if (q3 == 0) { 173 | charge -= (q2 % 2 == 0? 2: -1); 174 | } else { 175 | charge += (q2 % 2 == 0? 2: -1); 176 | charge += (q3 % 2 == 0? 2: -1); 177 | } 178 | 179 | return charge != 0; 180 | } 181 | 182 | 183 | void 184 | JetAnalysis::analyze(HepMC::GenEvent* event, map props){ 185 | 186 | std::vector particlesForJets; 187 | std::vector finalJets ; 188 | 189 | m_hs_calo.reset(); 190 | m_hs_calo.set_nInteractions(1); 191 | 192 | Calorimeter pu_calo (m_hs_calo); 193 | Calorimeter all_calo(m_hs_calo); 194 | all_calo.reset(); 195 | pu_calo .reset(); 196 | ExtendableJet ext; 197 | 198 | 199 | vector pjs; 200 | vector bhadrons; 201 | vector chadrons; 202 | vector tracks; 203 | 204 | HepMC::GenEvent::particle_const_iterator it; 205 | HepMC::FourVector mom; 206 | //cout << "#B~~~~~~~~~~~~~~~~~~~~" << endl; 207 | for(it=event->particles_begin(); it != event->particles_end(); it++){ 208 | int id = abs((*it)->pdg_id()); 209 | mom = (*it)->momentum(); 210 | PseudoJet pj(mom.px(), mom.py(), mom.pz(), mom.e()); 211 | 212 | //if its heavy flavor its ID will be -1*pdgid 213 | pj.set_user_index(-1*id); 214 | 215 | if (pj.perp() > 10 && is_final_qhadron(5, (*it))) { 216 | bhadrons.push_back(pj); 217 | } 218 | if (pj.perp() > 10 && is_final_qhadron(4, (*it))) { 219 | chadrons.push_back(pj); 220 | } 221 | 222 | //final state? 223 | if (!( (*it)->end_vertex() == NULL && (*it)->status()== 1)) continue; 224 | 225 | if (pj.perp() > 0.4 && is_charged(id)){ 226 | pj.set_user_index(-1); 227 | tracks.push_back(pj); 228 | } 229 | 230 | //neutrino or muon? 231 | if (id == 12 || id == 13 || id == 14 || id == 16) continue; 232 | 233 | //Drop electrons from a W decay 234 | //probably dont' want to do this for a b decay 235 | // if (id == 11 236 | // && (*it)->production_vertex() 237 | // && (*it)->production_vertex()->particles_in_size() == 1 238 | // && abs((*(*it)->production_vertex()->particles_in_const_begin())->pdg_id()) == 24) continue; 239 | // 240 | //if its not a heavy flavor its ID will become the cellindex 241 | pj.set_user_index(id); 242 | pjs.push_back(pj); 243 | } 244 | 245 | m_hs_calo.push(pjs); 246 | //cout << "#BThere are " << chadrons.size() << " c hadrons" << endl; 247 | 248 | //pu_calo = m_pug->next(); 249 | vector pu_calos = m_pug->next_vector(); 250 | for(unsigned int ii=0; ii=0 && nsaved >= m_saveMaxNJets ){ 283 | //cout << "too many jets in this event, skipping" << endl; 284 | break; 285 | } 286 | m_jetCuts.passed("NJets"); 287 | PseudoJet tj; 288 | double originalMass = finalJets[iJet].m(); 289 | 290 | if (m_trimJets == 1) tj = filter(finalJets[iJet]); 291 | else tj = finalJets[iJet]; 292 | 293 | if (! m_selPtMin.pass(tj)) {continue;} 294 | m_jetCuts.passed("PtMin"); 295 | 296 | if (! m_selPtMax.pass(tj)) {continue;} 297 | m_jetCuts.passed("PtMax"); 298 | 299 | if (! inMassRange(tj.m())) {continue;} 300 | m_jetCuts.passed("MassRange"); 301 | 302 | HepMC::GenParticle *bestParton; 303 | bestParton = findBestParton(tj, *event); 304 | if (! bestParton) { 305 | cout << "error: failed to find a bestparton" << endl; 306 | continue; 307 | } 308 | m_jetCuts.passed("BestParton"); 309 | 310 | unsigned int n_ga_bs = 0; 311 | unsigned int n_ga_cs = 0; 312 | unsigned int n_ga_tracks = 0; 313 | vector cons = tj.constituents(); 314 | for (unsigned int ii=0; ii= 0) continue; 317 | if(id == -1) ++n_ga_tracks; 318 | if(is_qhadron(4, -1 * id)) ++n_ga_cs; 319 | if(is_qhadron(5, -1 * id)) ++n_ga_bs; 320 | } 321 | 322 | nsaved+=1; 323 | 324 | ext = ExtendableJet(tj, all_calo, pu_calos, m_jetRadius, 2, m_trimRadius); 325 | ext.setProperty(props); 326 | ext.setProperty("pdgIDHardParton", bestParton->pdg_id()); 327 | ext.setProperty("preTrimMass", originalMass); 328 | ext.setProperty("n_b", n_ga_bs); 329 | ext.setProperty("n_c", n_ga_cs); 330 | ext.setProperty("n_tracks", n_ga_tracks); 331 | //ext.setProperty("bdrs_mass", get_bdrs_mass(finalJets[iJet], false)); 332 | ext.setProperty("bdrs_mass", get_bdrs_mass(finalJets[iJet], true)); 333 | 334 | std::map::iterator it; 335 | std::stringstream ss; 336 | for (it=m_nSubCalcs.begin(); it!=m_nSubCalcs.end(); ++it){ 337 | ss.str(""); 338 | ss << "tau_" << it->first; 339 | ext.setProperty(ss.str(), it->second->result(tj)); 340 | } 341 | //int id; 342 | //double dr; 343 | //if (id == 24) dr = eventInfo["wp_dr_prod"]; 344 | //else if (id == -24) dr = eventInfo["wm_dr_prod"]; 345 | //else dr = -999; 346 | //ext.setProperty("w_jet_dr", dr); 347 | 348 | if (m_doWTagger) { 349 | for (vector::const_iterator iEff = m_wtagEffs.begin(), iEffEnd = m_wtagEffs.end(); iEff != iEffEnd; ++iEff) { 350 | bool wtagged = wtag(csForJets, finalJets[iJet], *iEff / 100.); 351 | ss.str(""); 352 | ss << "wtag_" << *iEff; 353 | ext.setProperty(ss.str(), wtagged); 354 | } 355 | ext.setProperty("wtag_opt", wtag(csForJets, finalJets[iJet], -1)); 356 | } 357 | 358 | cout << "#G" << ext.toString(m_cellV) << endl; 359 | m_jetCuts.passed("Final"); 360 | } 361 | return; 362 | } 363 | 364 | std::vector 365 | JetAnalysis::selectGoodJets(fastjet::ClusterSequence &cs){ 366 | std::vector temp; 367 | 368 | std::vector everShrinking = fastjet::sorted_by_pt(cs.inclusive_jets()); 369 | everShrinking = m_basePtMin(everShrinking); 370 | temp = everShrinking; 371 | 372 | // fastjet::Selector dr = m_selDR; 373 | // for(unsigned int iJet=0; iJetstatus() > 80) continue; 395 | 396 | mom = pp->momentum(); 397 | pj = PseudoJet(mom.px(), mom.py(), mom.pz(), mom.e()); 398 | if (pj.delta_R(jet) > m_jetRadius) continue; 399 | 400 | if (best == NULL or pj.pt() > maxMetric){ 401 | best = pp; 402 | maxMetric = pj.pt(); 403 | } 404 | } 405 | 406 | return best; 407 | } 408 | 409 | double 410 | JetAnalysis::get_bdrs_mass(const PseudoJet &pj, bool require_two_bs) const{ 411 | unsigned int n_ga_bs;// = 0; 412 | PseudoJet mdt_jet = m_mdt.result(pj); 413 | 414 | //failed mass drop 415 | if (mdt_jet.pt() == 0) return -1; 416 | 417 | if (require_two_bs){ 418 | for(unsigned int i_jet=0; i_jet < mdt_jet.pieces().size(); ++i_jet){ 419 | n_ga_bs = 0; 420 | vector cons = mdt_jet.pieces()[i_jet].constituents(); 421 | for (unsigned int i_con=0; i_con= 0) continue; 424 | if(is_qhadron(5, -1 * id)) ++n_ga_bs; 425 | } 426 | //failed to have at least one b per subjet 427 | if (n_ga_bs < 1) return -2; 428 | } 429 | } 430 | double r_filt = min((double)0.3, (double)m_jetRadius/2); 431 | fastjet::Filter ff(fastjet::JetDefinition(fastjet::cambridge_algorithm,r_filt), 432 | fastjet::SelectorNHardest(3)); 433 | double mm = ff(mdt_jet).m(); 434 | return mm; 435 | } 436 | 437 | inline bool 438 | JetAnalysis::inMassRange(double jetMass) const { 439 | return m_jetMinM <= jetMass && jetMass <= m_jetMaxM; 440 | } 441 | -------------------------------------------------------------------------------- /runHerwig.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import time 3 | import sys 4 | import math 5 | import sys 6 | 7 | ##### 8 | def writeBasicInfo(nevents=100, seed=-1): 9 | 10 | 11 | text = """################################################## 12 | # First add MaxKT cuts 13 | ################################################## 14 | #cd /Herwig/Cuts 15 | #newdef JetKtCut:MaxKT 7000.0*GeV 16 | #newdef WBosonKtCut:MaxKT 7000.0*GeV 17 | #newdef ZBosonKtCut:MaxKT 7000.0*GeV 18 | #newdef TopKtCut:MaxKT 7000.0*GeV 19 | # 20 | 21 | 22 | ################################################## 23 | # Technical parameters for this run 24 | ################################################## 25 | cd /Herwig/Generators 26 | set LHCGenerator:NumberOfEvents %d 27 | set LHCGenerator:RandomNumberGenerator:Seed %d 28 | set LHCGenerator:DebugLevel 1 29 | set LHCGenerator:PrintEvent 10 30 | set LHCGenerator:MaxErrors 10000 31 | set LHCGenerator:EventHandler:StatLevel Full 32 | #set LHCGenerator:EventHandler:CascadeHandler NULL 33 | #Turning this off kills UE as well 34 | set /Herwig/Shower/ShowerHandler:MPIHandler NULL 35 | #set LHCGenerator:EventHandler:DecayHandler NULL 36 | #set LHCGenerator:EventHandler:HadronizationHandler NULL 37 | set /Herwig/Analysis/Basics:CheckQuark 0 38 | set LHCGenerator:EventHandler:LuminosityFunction:Energy 8000.0 39 | #set /Herwig/Shower/Evolver:IntrinsicPtGaussian 3.85*GeV 40 | set /Herwig/Shower/Evolver:IntrinsicPtGaussian 2.2*GeV 41 | 42 | """ % (nevents, seed) 43 | 44 | return text 45 | 46 | 47 | #### 48 | def writePDFInfo(): 49 | text = """################################################## 50 | # PDF parameters 51 | ################################################## 52 | cd /Herwig/Partons 53 | create ThePEG::LHAPDF LHAPDF ThePEGLHAPDF.so 54 | set LHAPDF:PType Nucleon 55 | set LHAPDF:PDFName cteq6ll.LHpdf 56 | set LHAPDF:PDFNumber 10042 57 | set LHAPDF:RemnantHandler HadronRemnants 58 | set /Herwig/Particles/p+:PDF LHAPDF 59 | set /Herwig/Particles/pbar-:PDF LHAPDF 60 | 61 | """ 62 | return text 63 | 64 | 65 | ### 66 | def writeUEtune(): 67 | text = """################################################## 68 | # Underlying Event Parameters 69 | ################################################## 70 | 71 | """ 72 | 73 | return text 74 | 75 | 76 | ##### 77 | def writeMatrixElementInfo(metype): 78 | text = """################################################## 79 | # Matrix Elements 80 | ################################################## 81 | cd /Herwig/MatrixElements/ 82 | """ 83 | 84 | if metype=='w': 85 | text +="""create Herwig::MEPP2VV MEPP2VV HwMEHadron.so 86 | insert SimpleQCD:MatrixElements[0] MEPP2VV 87 | set MEPP2VV:Process WW \n""" 88 | elif metype=="v": 89 | text +="""insert SimpleQCD:MatrixElements[0] MEWJet \n""" 90 | elif metype=="t": 91 | text +="""insert SimpleQCD:MatrixElements[0] MEHeavyQuark \n""" 92 | elif metype=="q": 93 | text +="""insert SimpleQCD:MatrixElements[0] MEQCD2to2 \n""" 94 | elif metype=="b": 95 | text +="""insert SimpleQCD:MatrixElements[0] MEHeavyQuark 96 | set MEHeavyQuark:QuarkType Bottom \n""" 97 | 98 | text += """\n""" 99 | 100 | return text 101 | 102 | 103 | ##### 104 | def writeKinematicCutInfo(metype,meminpt,memaxpt): 105 | text = """################################################## 106 | # Kinematic Cuts 107 | ##################################################""" 108 | 109 | if metype=='w' or metype=='v': 110 | text += """ 111 | set /Herwig/Cuts/WBosonKtCut:MinKT %d*GeV 112 | #set /Herwig/Cuts/WBosonKtCut:MaxKT %d*GeV 113 | set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV 114 | """ % (meminpt, memaxpt) 115 | elif metype=="t": 116 | text += """ 117 | set /Herwig/Cuts/TopKtCut:MinKT %d*GeV 118 | #set /Herwig/Cuts/TopKtCut:MaxKT %d*GeV 119 | set /Herwig/Cuts/JetKtCut:MinKT 0.0*GeV 120 | """ % (meminpt, memaxpt) 121 | elif metype=="q": 122 | text += """ 123 | set /Herwig/Cuts/JetKtCut:MinKT %d*GeV 124 | #set /Herwig/Cuts/JetKtCut:MaxKT %d*GeV 125 | """ % (meminpt, memaxpt) 126 | 127 | #file.write("set /Herwig/Cuts/ZBosonKtCut:MinKT "+str(meminpt)+"*GeV \n") 128 | #file.write("set /Herwig/Cuts/ZBosonKtCut:MaxKT "+str(memaxpt)+"*GeV \n") 129 | 130 | 131 | text += """\n""" 132 | 133 | return text 134 | 135 | 136 | ##### 137 | def writeParticleDecays(metype,lepcharge): 138 | 139 | Wp_lep = "Off" 140 | Wp_had = "Off" 141 | 142 | Wm_lep = "Off" 143 | Wm_had = "Off" 144 | 145 | # Z_lep = "Off" 146 | # Z_had = "Off" 147 | 148 | t_lep = "Off" 149 | t_had = "Off" 150 | 151 | tbar_lep = "Off" 152 | tbar_had = "Off" 153 | 154 | if lepcharge == 0: 155 | Wp_lep="On" 156 | Wm_lep="On" 157 | t_lep="On" 158 | tbar_lep="On" 159 | elif lepcharge == 1: 160 | Wp_lep="On" 161 | Wm_had="On" 162 | t_lep="On" 163 | tbar_had="On" 164 | elif lepcharge == -1: 165 | Wp_had="On" 166 | Wm_lep="On" 167 | t_had="On" 168 | tbar_lep="On" 169 | else: 170 | Wp_had="On" 171 | Wm_had="On" 172 | t_had="On" 173 | tbar_had="On" 174 | 175 | 176 | text="""################################################## 177 | # Particle Decays 178 | ################################################## 179 | set /Herwig/Particles/W+/W+->nu_e,e+;:OnOff Off 180 | set /Herwig/Particles/W+/W+->nu_mu,mu+;:OnOff %s 181 | set /Herwig/Particles/W+/W+->nu_tau,tau+;:OnOff Off 182 | set /Herwig/Particles/W+/W+->u,dbar;:OnOff %s 183 | set /Herwig/Particles/W+/W+->sbar,u;:OnOff %s 184 | set /Herwig/Particles/W+/W+->bbar,c;:OnOff %s 185 | set /Herwig/Particles/W+/W+->c,dbar;:OnOff %s 186 | set /Herwig/Particles/W+/W+->c,sbar;:OnOff %s 187 | """ % (Wp_lep, Wp_had, Wp_had, Wp_had, Wp_had, Wp_had) 188 | 189 | 190 | text += """set /Herwig/Particles/W-/W-->nu_ebar,e-;:OnOff Off 191 | set /Herwig/Particles/W-/W-->nu_mubar,mu-;:OnOff %s 192 | set /Herwig/Particles/W-/W-->nu_taubar,tau-;:OnOff Off 193 | set /Herwig/Particles/W-/W-->ubar,d;:OnOff %s 194 | set /Herwig/Particles/W-/W-->s,ubar;:OnOff %s 195 | set /Herwig/Particles/W-/W-->b,cbar;:OnOff %s 196 | set /Herwig/Particles/W-/W-->cbar,d;:OnOff %s 197 | set /Herwig/Particles/W-/W-->cbar,s;:OnOff %s 198 | """ % (Wm_lep, Wm_had, Wm_had, Wm_had, Wm_had, Wm_had) 199 | 200 | 201 | #set /Herwig/Particles/Z0/Z0->u,ubar;:OnOff Off 202 | #set /Herwig/Particles/Z0/Z0->b,bbar;:OnOff Off 203 | #set /Herwig/Particles/Z0/Z0->c,cbar;:OnOff Off 204 | #set /Herwig/Particles/Z0/Z0->d,dbar;:OnOff Off 205 | #set /Herwig/Particles/Z0/Z0->e-,e+;:OnOff On 206 | #set /Herwig/Particles/Z0/Z0->mu-,mu+;:OnOff Off 207 | #set /Herwig/Particles/Z0/Z0->nu_e,nu_ebar;:OnOff Off 208 | #set /Herwig/Particles/Z0/Z0->nu_mu,nu_mubar;:OnOff Off 209 | #set /Herwig/Particles/Z0/Z0->nu_tau,nu_taubar;:OnOff Off 210 | #set /Herwig/Particles/Z0/Z0->s,sbar;:OnOff Off 211 | #set /Herwig/Particles/Z0/Z0->tau-,tau+;:OnOff Off 212 | 213 | 214 | 215 | text += """ 216 | set /Herwig/Particles/t/t->nu_e,e+,b;:OnOff Off 217 | set /Herwig/Particles/t/t->nu_mu,mu+,b;:OnOff %s 218 | set /Herwig/Particles/t/t->nu_tau,tau+,b;:OnOff Off 219 | 220 | set /Herwig/Particles/t/t->b,u,dbar;:OnOff %s 221 | set /Herwig/Particles/t/t->b,c,sbar;:OnOff %s 222 | set /Herwig/Particles/t/t->b,sbar,u;:OnOff %s 223 | set /Herwig/Particles/t/t->b,c,dbar;:OnOff %s 224 | set /Herwig/Particles/t/t->b,bbar,c;:OnOff %s 225 | """ % (t_lep, t_had, t_had, t_had, t_had, t_had) 226 | 227 | text += """ 228 | set /Herwig/Particles/tbar/tbar->nu_ebar,e-,bbar;:OnOff Off 229 | set /Herwig/Particles/tbar/tbar->nu_mubar,mu-,bbar;:OnOff %s 230 | set /Herwig/Particles/tbar/tbar->nu_taubar,tau-,bbar;:OnOff Off 231 | set /Herwig/Particles/tbar/tbar->bbar,ubar,d;:OnOff %s 232 | set /Herwig/Particles/tbar/tbar->bbar,cbar,s;:OnOff %s 233 | set /Herwig/Particles/tbar/tbar->bbar,s,ubar;:OnOff %s 234 | set /Herwig/Particles/tbar/tbar->bbar,cbar,d;:OnOff %s 235 | set /Herwig/Particles/tbar/tbar->b,bbar,cbar;:OnOff %s 236 | """ % (tbar_lep, tbar_had, tbar_had, tbar_had, tbar_had, tbar_had) 237 | 238 | return text 239 | 240 | 241 | ##### 242 | def writeFinalAnalysisHandlerInfo(runname, runJetAnalysis=False): 243 | if runJetAnalysis: 244 | ss= ''' 245 | create HerwigWrapper::Evgen Evgen Evgen.so 246 | insert LHCGenerator:AnalysisHandlers 0 Evgen''' 247 | else: 248 | ss = ''' 249 | insert /Herwig/Generators/LHCGenerator:AnalysisHandlers[0] /Herwig/Analysis/HepMCFile 250 | set /Herwig/Analysis/HepMCFile:PrintEvent 999999999 251 | set /Herwig/Analysis/HepMCFile:Filename %s.hepmc 252 | set /Herwig/Analysis/HepMCFile:Format GenEvent 253 | set /Herwig/Analysis/HepMCFile:Units GeV_mm''' % runname 254 | 255 | return """ 256 | #set /Herwig/Analysis/HepMCFile:PrintEvent 9999999999 257 | ################################################## 258 | # Analysis Handler 259 | ################################################## 260 | cd /Herwig/Generators 261 | %s 262 | saverun %s LHCGenerator 263 | 264 | """ % (ss, runname) 265 | 266 | ##### 267 | def makeRunname(metype): 268 | import socket 269 | import os 270 | runname = '_'.join((metype, 271 | socket.gethostname(), 272 | str(os.getpid()), 273 | time.strftime('%b-%d-%Y-%H-%M-%S'))) 274 | 275 | return runname 276 | 277 | def createHerwigRunCard(outputfileName='run.in', runname='LHC-v', metype='v', lepcharge=1, meminpt=200, memaxpt=20000, seed=0, nevents=10): 278 | 279 | 280 | 281 | runcardText = writeBasicInfo(nevents, seed) \ 282 | + writePDFInfo() \ 283 | + writeUEtune() \ 284 | + writeMatrixElementInfo(metype) \ 285 | + writeKinematicCutInfo(metype,meminpt,memaxpt) \ 286 | + writeParticleDecays(metype,lepcharge) \ 287 | + writeFinalAnalysisHandlerInfo(runname) 288 | 289 | 290 | outfile = open(outputfileName, 'w') 291 | outfile.write(runcardText) 292 | outfile.close() 293 | 294 | return runname 295 | 296 | def readRunCard(cardfileName = 'run.in'): 297 | print "readRunCard %s:" % cardfileName 298 | args = ["Herwig++", "read", cardfileName] 299 | args = " ".join(args) 300 | print args 301 | result = subprocess.call(args, shell=True) 302 | return result 303 | 304 | def runHerwig(configName): 305 | print "runHerwig %s:" % configName 306 | args = ['Herwig++', 'run', configName] 307 | args = " ".join(args) 308 | print args 309 | result = subprocess.call(args, shell=True) 310 | return result 311 | 312 | def runHepMCJets(seed, metype, lepcharge 313 | , savemaxnjets, nevents 314 | , cellv, trimjet 315 | , jetminpt, jetmaxpt 316 | , jetminm, jetmaxm 317 | , rad, mu, smear 318 | , wtagger, input_file 319 | ): 320 | 321 | print "runHepMCJets:" 322 | 323 | args = ["hepmcJets.exe"] 324 | args += ["--seed=%s" % str(seed) , "--source=Herwig" , 325 | "--metype=%s" % str(metype) , "--lepcharge=%s" % str(lepcharge) , 326 | "--savemaxnjets=%s" % str(savemaxnjets) , "--nevents=%s" % str(nevents) , 327 | "--cellv=%s" % str(cellv) , "--trimjet=%s" % str(trimjet) , 328 | "--jetminpt=%s" % str(jetminpt) , "--jetmaxpt=%s" % str(jetmaxpt) , 329 | "--jetminm=%s" % str(jetminm) , "--jetmaxm=%s" % str(jetmaxm) , 330 | "--rad=%s" % str(rad) , "--mu=%s" % str(mu) , 331 | ] 332 | 333 | if smear: 334 | args.append("--smear") 335 | if wtagger: 336 | args.append("--wtagger") 337 | 338 | args.append(input_file) 339 | 340 | args = " ".join(args) 341 | print args 342 | result = subprocess.call(args, shell=True) 343 | return result 344 | 345 | def getSeed(optSeed): 346 | if optSeed > -1: return optSeed 347 | 348 | from time import time 349 | import os 350 | timeSeed = int(time() * pow(10,9)) 351 | 352 | return abs(((timeSeed*181)*((os.getpid()-83)*359))%104729) 353 | 354 | if __name__ == '__main__': 355 | import sys 356 | import argparse 357 | import subprocess 358 | 359 | print "Called with:" 360 | print " ".join(sys.argv) 361 | 362 | parser = argparse.ArgumentParser(description='Create a Herwig++ run card.') 363 | parser.add_argument('--seed' , default=-1 , type=int , help='The random number generator seed (-1 finds a random seed)') 364 | parser.add_argument('--savemaxnjets', default=-1 , type=int , help='Max number of jets to save. Default, -1, saves all jets (which satisfy other selectons)') 365 | parser.add_argument('--nevents' , default=100 , type=int , help='The generator number of events') 366 | parser.add_argument('--metype' , default='v' , type=str , choices = ['w', 'v', 't', 'q', 'b'] , help='Matrix element type') 367 | # parser.add_argument('--cardName' , default='run.in' , type=str , help='Output file name for Herwig++ run card name') 368 | parser.add_argument('--lepcharge' , default=1 , type=int , choices = [-1, 1, 0] , help='Charge of lepton desired in final state, only for ME ={v, t, W}. 1=l^+, -1=l^-, 0= All lepton flavors, any other value = no lepton (all hadronic)') 369 | parser.add_argument('--meminpt' , default=200 , type=int , help='Herwig++ MinKT (GeV) for v, t, and q') 370 | parser.add_argument('--memaxpt' , default=20000 , type=int , help='Herwig++ MaxKT (GeV) for v, t, and q') 371 | parser.add_argument('--jetminpt' , default=200 , type=int , help='Jet PTMin (GeV)') 372 | parser.add_argument('--jetmaxpt' , default=20000 , type=int , help='Jet PTMax (GeV)') 373 | parser.add_argument('--jetminm' , default=200 , type=int , help='Jet Min Mass (GeV)') 374 | parser.add_argument('--jetmaxm' , default=20000 , type=int , help='Jet Max Mass (GeV)') 375 | parser.add_argument('--cellv' , default=1 , type=int , choices = [0, 1] , help='Control how many and which cells to output. 0 shows no cells, 1 (default) shows only those that survive trimming and 2 shows all cells in a jet.') 376 | parser.add_argument('--trimjet' , default=1 , type=int , help='To run trimming or not. Any value other than 1 (default) disables trimming.') 377 | parser.add_argument('--rad' , default=0.4 , type=float , help='Jet Finder Radius') 378 | parser.add_argument('--mu' , default=0.0 , type=float , help='Average Int./Cross') 379 | parser.add_argument('--smear' , default=False , action='store_true' , help='Turn on radial energy smearing') 380 | parser.add_argument('--wtagger' , default=False , action='store_true' , help='Turn on MVA Tagger output') 381 | 382 | args = parser.parse_args() 383 | 384 | args.seed = getSeed(args.seed) 385 | 386 | sys.stdout.flush() 387 | print "" 388 | print "-+"*50 389 | print "makeRunname" 390 | runname = makeRunname(metype=args.metype) 391 | 392 | sys.stdout.flush() 393 | print "" 394 | print "-+"*50 395 | print "createHerwigRunCard" 396 | print createHerwigRunCard(outputfileName = runname + '.in', runname = runname 397 | , metype = args.metype, lepcharge = args.lepcharge 398 | , meminpt = args.meminpt, memaxpt = args.memaxpt 399 | , seed = args.seed, nevents = args.nevents 400 | ) 401 | 402 | print subprocess.call(['which', 'Herwig++']) 403 | 404 | sys.stdout.flush() 405 | print "" 406 | print "-+"*50 407 | print "readRunCard" 408 | print readRunCard(runname + '.in') 409 | 410 | sys.stdout.flush() 411 | print "" 412 | print "-+"*50 413 | print "runHerwig" 414 | print runHerwig(runname + '.run') 415 | 416 | sys.stdout.flush() 417 | print "" 418 | print "-+"*50 419 | print "runHepMCJets" 420 | print runHepMCJets(seed=args.seed, metype=args.metype, lepcharge=args.lepcharge 421 | , savemaxnjets=args.savemaxnjets, nevents=args.nevents 422 | , cellv=args.cellv, trimjet=args.trimjet 423 | , jetminpt=args.jetminpt, jetmaxpt=args.jetmaxpt 424 | , jetminm=args.jetminm, jetmaxm=args.jetmaxm 425 | , rad=args.rad, mu=args.mu, smear=args.smear 426 | , wtagger=args.wtagger, input_file=runname + '.hepmc' 427 | 428 | ) 429 | sys.stdout.flush() 430 | -------------------------------------------------------------------------------- /rotate_jets.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import math 4 | import numpy as np 5 | import numpy.linalg as linalg 6 | import matplotlib as mpl 7 | import matplotlib.ticker as ticker 8 | from matplotlib.colors import LogNorm 9 | import matplotlib.pyplot as plt 10 | import matplotlib.cm as cm 11 | import scipy.interpolate as inp 12 | from scipy.ndimage.interpolation import geometric_transform 13 | from matplotlib import rc 14 | rc('font', **{'family':'serif'})#, 'serif':['Times']}) 15 | rc('text', usetex=True) 16 | rc('axes', linewidth=2) 17 | rc('xtick.major', width=2) 18 | rc('ytick.major', width=2) 19 | 20 | np.set_printoptions(precision=3, suppress=True) 21 | 22 | def handleCLI(): 23 | from optparse import OptionParser 24 | usage = '%prog [opts] -i myInput.txt -o myOuput.{npy,pdf}' 25 | pp = OptionParser(usage=usage) 26 | pp.add_option('-n', '--njets', dest='njets', type=int, default=-1, 27 | help='Specify number of jets (or images) to rotate.' 28 | ' Specifying -1 runs on the entire sample.' 29 | ' Currently the run is tacitly truncated at 10K') 30 | pp.add_option('-j', '--subjets', dest='subjets', action='store_true', 31 | help='Use subjets to find the transformation parameters,' 32 | ' otherwise, the default uses prinicple axes') 33 | 34 | pp.add_option('-t', '--target', dest='target', type=float, default=None, 35 | help='Specify the target (along the axis after rotation)' 36 | ' of the leading subjet. Defaults to None when it is ignored') 37 | 38 | pp.add_option('-l', '--length', dest='length', type=float, default=None, 39 | help='Specify the distance between the two subjets as a' 40 | ' fraction of the total image length. -1 to ignore.') 41 | 42 | pp.add_option('-i', '--input', dest='input', type=str, default=None, 43 | help='Specify input file of unrotated text-jets') 44 | 45 | pp.add_option('-o', '--output', dest='output', type=str, default=None, 46 | help='Specify output file. If the extension is .npy' 47 | ' then a numpy file is of rotated jets is created.' 48 | ' If a .pdf extension is used then some plots are made' 49 | ' instead.') 50 | 51 | # pp.add_option('-s', '--static', dest='static', action='store_true', 52 | # default=False, 53 | # help='Do no rotation and put on plot on a page') 54 | 55 | opts, args = pp.parse_args() 56 | if None in (opts.output, opts.input): 57 | pp.print_usage() 58 | sys.exit(1) 59 | 60 | #print "Rotating Jets" 61 | #print opts, args 62 | return opts, args 63 | 64 | def deltaR(aa, bb): 65 | dphi = abs(aa[1] - bb[1]) 66 | dphi = (2*math.pi - dphi) if dphi > math.pi else dphi 67 | return math.sqrt((aa[0] - bb[0])**2 + dphi**2) 68 | 69 | 70 | def getPrincipleAxes(theMat): 71 | 72 | if theMat.shape != (2,2): 73 | print "ERROR: getPrincipleAxes(theMat), theMat size is not 2x2. DYING!" 74 | sys.exit(1) 75 | 76 | laS, laV = linalg.eigh(theMat) 77 | return -1*laV[::-1], laS[::-1] 78 | 79 | def makeXYScatterMatrix(record, pow_forScat=1, pow_forMean=1): 80 | jet_rad = record['radius'] 81 | #eta_off = record['eta'] - record['jet_offset'][0] 82 | #phi_off = record['phi'] - record['jet_offset'][1] 83 | 84 | cell_values = np.array([cell[0] for cell in record['cells']]) 85 | cell_x = np.array([cell[1] for cell in record['cells']]) 86 | cell_y = np.array([cell[2] for cell in record['cells']]) 87 | cell_values = np.array(cell_values) 88 | 89 | 90 | eta_off = (np.max(cell_x) + np.min(cell_x))/2 91 | phi_off = (np.max(cell_y) + np.min(cell_y))/2 92 | 93 | mask = ( (np.square(cell_x - eta_off) 94 | + np.square(cell_y - phi_off)) < jet_rad**2) 95 | 96 | etot = np.sum((cell_values>0) * np.power(cell_values, pow_forMean)) 97 | if etot == 0: 98 | print 'Found a jet with no energy. DYING!' 99 | sys.exit(1) 100 | 101 | x_1 = np.sum((cell_values>0) * np.power(cell_values, pow_forMean) * cell_x)/etot 102 | y_1 = np.sum((cell_values>0) * np.power(cell_values, pow_forMean) * cell_y)/etot 103 | x_2 = np.sum(mask * (cell_values>0) * np.power(cell_values, pow_forScat) * np.square(cell_x -x_1)) 104 | y_2 = np.sum(mask * (cell_values>0) * np.power(cell_values, pow_forScat) * np.square(cell_y -y_1)) 105 | xy = np.sum(mask * (cell_values>0) * np.power(cell_values, pow_forScat) * (cell_x - x_1)*(cell_y -y_1)) 106 | 107 | ScatM = np.array([[x_2, xy],[xy, y_2]]) 108 | MeanV = np.array([x_1, y_1]) 109 | 110 | return ScatM, MeanV 111 | 112 | def getMaxPartialSum(record, n_side_partial=2): 113 | cell_values = np.array([cell[0] for cell in record['cells']]) 114 | cell_x = np.array([cell[1] for cell in record['cells']]) 115 | cell_y = np.array([cell[2] for cell in record['cells']]) 116 | cell_values = np.array(cell_values) 117 | 118 | n_side = int(np.sqrt(cell_x.shape[0])) 119 | cell_values = cell_values.reshape(n_side, n_side) 120 | cell_x = cell_x.reshape(n_side, n_side) 121 | cell_y = cell_y.reshape(n_side, n_side) 122 | 123 | 124 | max_partial_sum = -1 125 | max_x_y = np.array([-1.0,-1.0]) 126 | for xbin in range(n_side - n_side_partial): 127 | for ybin in range(n_side - n_side_partial): 128 | partial_sum = np.sum(cell_values[ybin:ybin+2, xbin:xbin+2]) 129 | 130 | if partial_sum <= 0: 131 | continue 132 | 133 | if partial_sum > max_partial_sum: 134 | max_partial_sum = partial_sum 135 | max_x_y[0] = np.sum( cell_x[ybin:ybin+2, xbin:xbin+2] * cell_values[ybin:ybin+2, xbin:xbin+2] ) / partial_sum 136 | max_x_y[1] = np.sum( cell_y[ybin:ybin+2, xbin:xbin+2] * cell_values[ybin:ybin+2, xbin:xbin+2] ) / partial_sum 137 | 138 | return max_partial_sum, max_x_y 139 | 140 | 141 | def etaPhiToCellCoords(ptEtaPhiTriplet):#, startLocation): 142 | 143 | return (ptEtaPhiTriplet['eta'], ptEtaPhiTriplet['phi']) 144 | return ptEtaPhiTriplet[1:3] 145 | dEta = ptEtaPhiTriplet[1] - startLocation[0] 146 | dPhi = ptEtaPhiTriplet[2] - startLocation[1] 147 | 148 | return dEta, dPhi 149 | 150 | #def geoBoostCells(record, do_principles, length_frac, y_target, use_pt): 151 | # 152 | # sideLength = int(math.sqrt(record['n_cells'])) 153 | # 154 | # cell_x = np.array(record['cells']['eta']) 155 | # cell_y = np.array(record['cells']['phi']) 156 | # cell_values = np.array(record['cells']['E' ]) 157 | # if use_pt is True: 158 | # cell_values /= np.cosh(cell_x) 159 | # cell_points = np.column_stack((cell_x, cell_y)) 160 | 161 | 162 | def geoTransCells(record, do_principles, length_frac, y_target, ): 163 | 164 | sideLength = int(math.sqrt(record['n_cells'])) 165 | 166 | cell_x = np.array(record['cells']['eta']) 167 | cell_y = np.array(record['cells']['phi']) 168 | cell_values = np.array(record['cells']['E' ]) 169 | cell_points = np.column_stack((cell_x, cell_y)) 170 | 171 | ll=1.0 172 | ctheta=0.0 173 | stheta=0.0 174 | centerX=0.0 175 | centerY=0.0 176 | imageLength = np.max(cell_y) - np.min(cell_y) 177 | partial_sum = 0 178 | partial_coords = np.array([-1.0,-1.0]) 179 | 180 | #we know we have at least 1 subjet 181 | bigJet = etaPhiToCellCoords( record['rel_subjets'][0] )#, record['jet_offset']) 182 | smallJet = etaPhiToCellCoords( record['rel_subjets'][1] )#, record['jet_offset']) 183 | jet = [record['eta']-record['jet_offset'][0], record['phi']-record['jet_offset'][1]] 184 | if jet[1] < 0: 185 | jet[1] += 2 * math.pi 186 | 187 | 188 | if do_principles: 189 | scat, cent = makeXYScatterMatrix(record) 190 | paxes, pvars = getPrincipleAxes(scat) 191 | ll = pvars[0]/sideLength 192 | 193 | partial_sum, partial_coords = getMaxPartialSum(record) 194 | #check sign of rotation is correct for lead jet on top 195 | paxes[0,:] = paxes[0,:] * np.sign( np.dot(paxes[0,:], bigJet[0:2] - cent[0:2]) ) 196 | 197 | stheta = paxes[0,0] 198 | ctheta = paxes[0,1] 199 | centerX = cent[0] 200 | centerY = cent[1] 201 | else: 202 | #in this case, we know we have second subjet 203 | 204 | ll = math.sqrt((bigJet[0] - smallJet[0])**2 +(bigJet[1] - smallJet[1])**2) 205 | ctheta = (bigJet[1] - smallJet[1])/ll 206 | stheta = (bigJet[0] - smallJet[0])/ll 207 | #centerX = (record['rel_subjets'][0]['E']*bigJet[0] + record['rel_subjets'][1]['E']*smallJet[0])/np.sum(record['rel_subjets'][:2]['E']) 208 | #centerY = (record['rel_subjets'][0]['E']*bigJet[1] + record['rel_subjets'][1]['E']*smallJet[1])/np.sum(record['rel_subjets'][:2]['E']) 209 | #print centerX, centerY 210 | centerX = (bigJet[0] + smallJet[0])/2 211 | centerY = (bigJet[1] + smallJet[1])/2 212 | #print centerX, centerY 213 | 214 | wCenterX = (np.max(cell_x) + np.min(cell_x))/2 215 | wCenterY = (np.max(cell_y) + np.min(cell_y))/2 216 | 217 | #wLength = sideLength*0.5 218 | #wLength = ll * 0.2 / deltaR(bigJet, jet) 219 | #print wLength/ll 220 | 221 | if length_frac > 0: 222 | wLength = length_frac * imageLength 223 | else: 224 | wLength = ll 225 | 226 | if y_target is not None: 227 | if do_principles: 228 | wCenterY = y_target + wLength/2 229 | else: 230 | wCenterY = y_target - wLength/2 231 | 232 | 233 | R = np.matrix([[ctheta, -stheta],[stheta,ctheta]]) 234 | S = np.matrix([[1,0],[0,wLength/ll]]) 235 | CH = np.matrix([[centerX],[centerY]]) 236 | CW = np.matrix([[wCenterX],[wCenterY]]) 237 | try: 238 | Rinv = linalg.inv(R) 239 | Sinv = linalg.inv(S) 240 | except np.linalg.linalg.LinAlgError, e: 241 | print 'Failed on eventNumber %d with seed %d' % (record['eventNumber'], record['seed']) 242 | raise e 243 | 244 | 245 | 246 | def shift_func(coords): 247 | # used in passive rotations, which is used for rotating the grid 248 | C = np.matrix(coords).getT() 249 | 250 | A = (Rinv * (Sinv * (C - CW)) + CH) 251 | A = A.getA1() 252 | return A 253 | 254 | def shift_func_inv(coords): 255 | # used in active rotations, which is used for rotating the individual points for display 256 | # and used for calculating the offsets when targets are specified 257 | C = np.matrix(coords).getT() 258 | 259 | A = S * (R* (C - CH)) + CW 260 | A = A.getA1() 261 | return A 262 | 263 | test_x = np.linspace(min(cell_x), max(cell_x), sideLength) 264 | test_y = np.linspace(min(cell_y), max(cell_y), sideLength) 265 | 266 | test_grid = np.zeros((test_x.shape[0], test_y.shape[0], 2)) 267 | 268 | orig_grid_x, orig_grid_y = np.meshgrid(test_x, test_y) 269 | test_grid[:,:,0] = orig_grid_x 270 | test_grid[:,:,1] = orig_grid_y 271 | test_points = test_grid.reshape((test_grid.shape[0] * test_grid.shape[1], 2)) 272 | test_points = np.array([shift_func(point) for point in test_points]) 273 | 274 | test_values = inp.griddata(cell_points, cell_values, test_points, fill_value=0) 275 | 276 | orig_values = listToGrid(cell_values) 277 | rot_values = listToGrid(test_values) 278 | return orig_grid_x, orig_grid_y, \ 279 | orig_values, rot_values , \ 280 | np.array(shift_func_inv(bigJet [0:2])), \ 281 | np.array(shift_func_inv(smallJet[0:2])) 282 | 283 | 284 | def listToGrid(ra): 285 | oldShape = ra.shape 286 | newLen = int(math.sqrt(oldShape[0])) 287 | newShape = (newLen, newLen) + ra.shape[1:] 288 | 289 | return ra.reshape(newShape) 290 | 291 | def reflect(cells, axis=1): 292 | 293 | if axis not in [0,1]: 294 | print "Reflect Error: axis must be either 0 or 1!" 295 | return 296 | 297 | lx,ly = cells.shape 298 | 299 | if axis == 1: 300 | # flip over y-axis 301 | #bounds to exclude the central stripe, needs odd number of bins 302 | left = np.sum(cells[:, ly/2+1: ]) 303 | right = np.sum(cells[:, :ly/2]) 304 | 305 | if left > right: 306 | return cells, False 307 | 308 | return cells[:,::-1], True 309 | 310 | # if here, axis must be 0 311 | # flip over x-axis 312 | #bounds to exclude the central stripe, needs odd number of bins 313 | top = np.sum(cells[lx/2+1: ,:]) 314 | bottom = np.sum(cells[ :lx/2,:]) 315 | print top, bottom 316 | 317 | if top > bottom: 318 | return cells, False 319 | 320 | return cells[::-1,:], True 321 | 322 | def plotStuff(pp, orig_values, rot_values, orig_subjets, rot_subjets): 323 | 324 | fig = plt.figure(figsize=(5, 5)) 325 | fig.subplots_adjust(top=.97, right=.95, 326 | left=0.13, bottom=.13) 327 | size = .80 328 | vmax = 2 * 10**3 329 | vmin = 5e-4 330 | 331 | ll = int(orig_values.shape[0]) 332 | low = -.1 333 | high = ll/10.0 + .1 334 | 335 | for do_rot in (False, True, ): 336 | subjets = rot_subjets if do_rot else orig_subjets 337 | for do_legend in (False, True, ): 338 | fig.clf() 339 | 340 | ax = fig.add_axes((0.15, 0.12, size, size)) 341 | ret = ax.imshow(orig_values if not do_rot else rot_values, 342 | cmap=cm.jet, 343 | norm=LogNorm(), 344 | interpolation='nearest', 345 | origin='lower', 346 | extent=[low, high, low, high], 347 | vmin=vmin, 348 | vmax=vmax, 349 | ) 350 | if subjets is not None and len(subjets) > 1: 351 | for ii, li in enumerate([('Leading Subjet', 'o'), 352 | ('2$^{\\mathbf{nd}}$ Subjet', 'v')]): 353 | 354 | ax.scatter( subjets[ii][0], subjets[ii][1], 355 | s=200, edgecolor='#a61700', facecolor='None', 356 | linewidths=3, marker=li[1],label=li[0]) 357 | if do_rot: 358 | ax.set_ylabel('Q$_{\\mathbf{1}}$', fontsize='x-large', labelpad=9) 359 | ax.set_xlabel('Q$_{\\mathbf{2}}$', fontsize='x-large', labelpad=12) 360 | else: 361 | ax.set_ylabel('Relative $\\mathbf{\phi}$', fontsize='x-large', labelpad=9) 362 | ax.set_xlabel('Relative $\\mathbf{\eta}$', fontsize='x-large', labelpad=12) 363 | 364 | _ticks = np.linspace(0, ll/10.0, 6) 365 | ax_fmt = ticker.FormatStrFormatter('$\\mathbf{%s}$') 366 | ax.tick_params(axis='both', labelsize='large') 367 | ax.xaxis.set_major_formatter(ax_fmt) 368 | ax.yaxis.set_major_formatter(ax_fmt) 369 | ax.set_xticks(_ticks) 370 | ax.set_yticks(_ticks) 371 | 372 | if do_legend: 373 | ax_cbar = fig.add_axes((0.78,0.25,0.05,0.5)) 374 | seq = ['$\\mathbf{10^{%d}}$' % ii for ii in range( 375 | int(math.ceil(math.log10(vmin))), 376 | int(math.log10(vmax)) + 1) 377 | ] 378 | cb_fmt = ticker.FixedFormatter(seq) 379 | ax_cbar.set_xlabel('$\\mathbf{p_T}$ [GeV]', labelpad=9) 380 | ax_cbar.tick_params(axis='both', labelsize='large') 381 | cbar = fig.colorbar(ret, ax_cbar, format=cb_fmt) 382 | leg = ax.legend(loc='upper right', frameon=True, scatterpoints=1, 383 | #fontsize='large') 384 | ) 385 | leg.get_frame().set_edgecolor('white') 386 | leg.get_frame().set_facecolor('white') 387 | 388 | plt.savefig(pp, format='pdf') 389 | 390 | 391 | def rotationStuff(in_name, out_name, n_jets, do_principles, y_target, length_frac, Use_Y_Reflection = True): 392 | 393 | if out_name.endswith('pdf'): 394 | from matplotlib.backends.backend_pdf import PdfPages 395 | pp = PdfPages(out_name) 396 | #print 'Writing pdf' 397 | import InputCleaner as ic 398 | incoming = ic.InputCleanerGen([in_name],sys.stdin, search='^#G(.*)$') 399 | 400 | whichJet = 0 401 | 402 | import text2bin 403 | ra = text2bin.makeNumpyArray(incoming, n_jets) 404 | if n_jets == -1: 405 | n_jets = len(ra) 406 | ra = ra[:n_jets] 407 | out_array = np.array(ra) 408 | 409 | for rr in out_array: 410 | n_subjets = np.count_nonzero(rr['rel_subjets']['E']) 411 | n_cells = np.count_nonzero(rr['cells']['E']) 412 | if n_subjets <1: 413 | continue 414 | if not do_principles and n_subjets <2: 415 | continue 416 | if n_cells <2: 417 | continue 418 | 419 | orig_grid_x, orig_grid_y, orig_values,\ 420 | rot_values, shiftBigJet, shiftSmallJet = geoTransCells(rr, do_principles, length_frac, y_target, ) 421 | 422 | #reflect over y-axis. But not if there is a target, because then axis is already shifted and reflection can throw things out of grid 423 | if do_principles and Use_Y_Reflection and y_target == None: 424 | rot_values, isrefY = reflect(rot_values, axis=0) 425 | print 'reflecting y', isrefY 426 | if isrefY: 427 | shiftBigJet[1] = np.max(orig_grid_y[:,0])+np.min(orig_grid_y[:,0]) - shiftBigJet[1] 428 | shiftSmallJet[1] = np.max(orig_grid_y[:,0])+np.min(orig_grid_y[:,0]) - shiftSmallJet[1] 429 | 430 | 431 | #obligatory reflection along x axis 432 | rot_values, isrefX = reflect(rot_values, axis=1) 433 | print 'reflecting x', isrefX 434 | if isrefX: 435 | shiftBigJet[0] = np.max(orig_grid_x[0])+np.min(orig_grid_x[0]) - shiftBigJet[0] 436 | shiftSmallJet[0] = np.max(orig_grid_x[0])+np.min(orig_grid_x[0]) - shiftSmallJet[0] 437 | 438 | 439 | out_array['cells'][whichJet] = rot_values.reshape(1, rot_values.shape[0]*rot_values.shape[1]) 440 | 441 | #used to make no rotation set 442 | # orig_values = rr['cells']['E'] 443 | # out_array['cells'][whichJet] = orig_values#.reshape(1, orig_values.shape[0]*orig_values.shape[1]) 444 | 445 | whichJet += 1 446 | if not out_name.endswith('pdf'): 447 | continue 448 | 449 | orig_subjets = [(rr['rel_subjets'][0][1], rr['rel_subjets'][0][2]), 450 | (rr['rel_subjets'][1][1], rr['rel_subjets'][1][2])] 451 | plotStuff(pp, orig_values, rot_values, orig_subjets, [shiftBigJet, shiftSmallJet]) 452 | 453 | try: 454 | pp.close() 455 | return 456 | except NameError: 457 | pass 458 | 459 | out_array = out_array[out_array['m']>-1] 460 | fh = open(out_name, 'w') 461 | np.save(fh, out_array) 462 | fh.close() 463 | 464 | print 'Saved %d jets' % whichJet 465 | 466 | return ra, out_array 467 | 468 | 469 | def main(): 470 | opts, args = handleCLI() 471 | 472 | rotationStuff(opts.input, opts.output, opts.njets, 473 | not opts.subjets, opts.target, opts.length) 474 | 475 | 476 | if __name__ == '__main__': 477 | main() 478 | -------------------------------------------------------------------------------- /simpleED.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import math 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | import matplotlib.ticker as tck 6 | import matplotlib.gridspec as grdspc 7 | import InputCleaner as ic 8 | 9 | PI = math.pi 10 | 11 | def makeNCaloImages(pdfpages, listOfRecords): 12 | iRecord = 0 13 | key = 'cells' 14 | 15 | nRows = 4 16 | nCols = 4 17 | wRatio = 1 18 | combinedFig = plt.figure() 19 | combinedFig.suptitle('$<\\mu>=0') 20 | 21 | for record in listOfRecords: 22 | isRight = ((iRecord+1)%nCols == 0) 23 | isLeft = ((iRecord )%nCols == 0) 24 | isTop = ((iRecord/nRows) == 0) 25 | isBottom = ((iRecord/nRows) >= nRows - 1) 26 | 27 | #cells = sorted(record[key], key=lambda pp: 28 | #pts = np.array([pp[0] for pp in record[key]]) 29 | #etas = np.array([pp[1] for pp in record[key]]) 30 | #phis = np.array([pp[2] for pp in record[key]]) 31 | pts = np.array([pp[0] for pp in record[key]]) 32 | 33 | n_on_side = math.sqrt(pts.shape[0]) 34 | pts = pts.reshape(n_on_side, n_on_side) 35 | 36 | print pts 37 | print pts.shape 38 | ax = combinedFig.add_subplot(nRows, nCols, iRecord+1) 39 | 40 | print 'Im showing' 41 | ax.imshow(pts, interpolation='nearest') 42 | print 'Im showing' 43 | #ax.contourf(etas, phis, pts) 44 | 45 | if isLeft: 46 | ax.set_ylabel(r'$\phi$') 47 | else: 48 | ax.set_yticklabels([]) 49 | 50 | if isBottom: 51 | ax.set_xlabel(r'$Cos \theta$') 52 | else: 53 | ax.set_xticklabels([]) 54 | 55 | iRecord += 1 56 | if iRecord == nCols * nRows: 57 | break 58 | 59 | plt.savefig(pdfpages, format='pdf') 60 | 61 | def makeNImages(pdfpages, listOfRecords, title, testFunction=None, doBoost=True): 62 | iRecord = 0 63 | key = ('bParts' if doBoost else 'parts') 64 | key = 'cells' 65 | 66 | nRows = 4 67 | nCols = 4 68 | wRatio = 1 69 | combinedFig = plt.figure() 70 | combinedFig.suptitle(('Unboosted ' if doBoost else 'Lab Frame ') + title) 71 | #gs_comb = grdspc.GridSpec(nRows,nCols,wspace=0.08,width_ratios=wRatio) 72 | # for ii, record in enumerate(listOfRecords): 73 | # print record['eventNumber'] 74 | # print ['%.2f' % record[key][ii][2] for ii in range(record['nParts'])] 75 | # if ii >= 10: break 76 | for record in listOfRecords: 77 | 78 | isRight = ((iRecord+1)%nCols == 0) 79 | isLeft = ((iRecord )%nCols == 0) 80 | isTop = ((iRecord/nRows) == 0) 81 | isBottom = ((iRecord/nRows) >= nRows - 1) 82 | 83 | particles = sorted(record[key], key=lambda li:li[1], reverse=False) 84 | ids = [pp[0] for pp in particles] 85 | # if boosted, then these are really energies 86 | pts = [pp[1] for pp in particles] 87 | # if boosted, then these are really cosThetas 88 | etas = [pp[2] for pp in particles] 89 | phis = [pp[3] for pp in particles] 90 | 91 | # ids = [record[key][ii][0] for ii in range(record['nParts'])] 92 | # # if boosted, then these are really energies 93 | # pts = [record[key][ii][1] for ii in range(record['nParts'])] 94 | # # if boosted, then these are really cosThetas 95 | # etas = [record[key][ii][2] for ii in range(record['nParts'])] 96 | # phis = [record[key][ii][3] for ii in range(record['nParts'])] 97 | 98 | ids = np.array(ids ) 99 | pts = np.array(pts ) #/ (record['m'] if doBoost else record['pt']) 100 | etas = np.array(etas) 101 | phis = np.array(phis) 102 | 103 | pts = pts/np.cosh(etas) 104 | pts = np.minimum(pts, 10*np.ones(*pts.shape)) 105 | ylims = (0, 6.29) #purposefuly a smidge larger than 2*pi 106 | xlims = (-2.5, 2.5) 107 | 108 | if not doBoost: 109 | #etas -= record['eta'] 110 | #phis -= record['phi'] 111 | #phis = np.where(phis > PI, phis-2*PI, phis) 112 | #phis = np.where(phis <-PI, phis+2*PI, phis) 113 | phis = np.where(phis < 0, 2*PI+phis, phis) 114 | 115 | #etas *= 10 116 | #phis *= 10 117 | #ylims = (-10, 10) 118 | #xlims = (-10, 10) 119 | pass 120 | 121 | aids = abs(ids) 122 | #charged pi/K/p 123 | hads = np.any([aids == 211, aids==321, aids==2212], axis=0) 124 | #charged e/mu 125 | leps = np.any([aids==11, aids==13], axis=0) 126 | 127 | cells = (aids == 0) 128 | 129 | markers = [ 130 | (cells , 'b' , 's', 0.1, 'Cells'), 131 | (hads , 'b' , 'o', 0.05, 'Hadrons'), 132 | #(hads , 'b' , 'o', 'Hadrons'), 133 | #(ids == 22, '#FF9900', 's', 'Photons'), 134 | #(leps , '#A80000', 's', 'Leptons'), 135 | ] 136 | 137 | ax = combinedFig.add_subplot(nRows, nCols, iRecord+1) 138 | lines = [] 139 | labels = [] 140 | if False:#not doBoost: 141 | c1 =plt.Circle((record['eta'],record['phi']),record['radius'], 142 | color='r',fill=False, zorder=100) 143 | c2 =plt.Circle((record['eta'],record['phi']+2*PI),record['radius'], 144 | color='r',fill=False, zorder=100) 145 | c3 =plt.Circle((record['eta'],record['phi']-2*PI),record['radius'], 146 | color='r',fill=False, zorder=10) 147 | plt.gcf().gca().add_artist(c1) 148 | plt.gcf().gca().add_artist(c2) 149 | plt.gcf().gca().add_artist(c3) 150 | 151 | for sliceObj, cc, mm, userLinSize, label in markers: 152 | 153 | if 0 == etas[sliceObj].shape[0]: 154 | continue 155 | 156 | 157 | ax.set_xlim(*xlims) 158 | ax.set_ylim(*ylims) 159 | ax.get_yaxis().set_major_locator(tck.MaxNLocator(nbins=5, integer=True)) 160 | ax.get_xaxis().set_major_locator(tck.MaxNLocator(nbins=5, integer=True)) 161 | 162 | # line = ax.scatter(etas[sliceObj], phis[sliceObj], c=pts[sliceObj], 163 | # label=label, edgecolors='none', s=1, marker=mm, alpha=1.0) 164 | 165 | origTest = (xlims[0], ylims[0]) 166 | dxTest = [xx + userLinSize for xx in origTest] 167 | dsp = ax.transData.transform([origTest, dxTest]) 168 | dataSize = (dsp[0][0] - dsp[1][0])*(dsp[0][1]-dsp[1][1]) 169 | print userLinSize, dsp, dataSize 170 | #dataSize *= 1000 171 | line = ax.scatter(etas[sliceObj], phis[sliceObj], c=pts[sliceObj], 172 | label=label, edgecolors='none', s=dataSize, 173 | marker=mm, alpha=1.0, zorder=50) 174 | 175 | if isLeft: 176 | if doBoost: 177 | ax.set_ylabel(r'$\phi$') 178 | else: 179 | ax.set_ylabel(r'$\Delta \phi \times \mathit{10}$') 180 | else: 181 | #ax.tick_params(axis='y', length=0, width=0) 182 | ax.set_yticklabels([]) 183 | 184 | if isBottom: 185 | if doBoost: 186 | ax.set_xlabel(r'$Cos \theta$') 187 | else: 188 | ax.set_xlabel(r'$\Delta \eta \times \mathit{10}$') 189 | else: 190 | #ax.tick_params(axis='x', length=0, width=0) 191 | ax.set_xticklabels([]) 192 | 193 | lines.append(line) 194 | labels.append(label) 195 | 196 | #fig.legend(lines, labels) 197 | 198 | iRecord += 1 199 | if iRecord == nCols * nRows: 200 | break 201 | 202 | plt.savefig(pdfpages, format='pdf') 203 | 204 | def makeGroups(fnames, rangeA=None, rangeB=None): 205 | retDi = {'q': {}, 'g':{}, 'w': {}} 206 | retDi = {'q': [], 'g':[], 'w': []} 207 | 208 | if rangeA is None: 209 | low, high = None, None 210 | elif rangeB is None: 211 | low, high = 0, rangeA 212 | else: 213 | low, high = rangeA, rangeB 214 | 215 | # for kk, di in retDi.iteritems(): 216 | # for ii in range(low, high): 217 | # di[ii] = [] 218 | 219 | for fname in fnames: 220 | records = np.load(open(fname)) 221 | for rec in records: 222 | flavor = 'w' if rec['ME'] == 2 else ('g' if rec['pdgIDHardParton'] == 21 else 'q') 223 | nParts = rec['nParts'] 224 | retDi[flavor].append(rec) 225 | #if high > nParts >= low: 226 | # retDi[flavor][nParts].append(rec) 227 | 228 | return retDi 229 | 230 | def powerSpectrum(records, lmax=40): 231 | import scipy.special as spe 232 | print '~'*50 233 | print records 234 | print '~'*50 235 | 236 | key = 'bParts' 237 | power = np.zeros(shape=(lmax, len(records))) 238 | for iRecord, rec in enumerate(records): 239 | es = [rec[key][ii][1] for ii in range(rec['nParts'])] 240 | cosTs = [rec[key][ii][2] for ii in range(rec['nParts'])] 241 | phis = [rec[key][ii][3] for ii in range(rec['nParts'])] 242 | 243 | thetas = np.arccos(cosTs) 244 | phis = np.array(phis) 245 | es = np.array(es) 246 | #es /= np.sum(es*es) 247 | es /= math.sqrt(np.sum(es*es)) 248 | 249 | for ll in range(lmax): 250 | for mm in range(-ll, ll+1): 251 | #note scipy takes opposite unit names from Physics 252 | #phi (in scipy) is angle from z-axis 253 | flm = np.sum( spe.sph_harm(mm, ll, phis, thetas) * es) 254 | #flm = np.sum(np.sin(thetas) * spe.sph_harm(mm, ll, phis, thetas) * es) 255 | power[ll,iRecord] += np.abs(flm + np.conj(flm)) 256 | 257 | 258 | 259 | power = np.sqrt(power) 260 | return power 261 | 262 | class FourVector: 263 | def __init__(self, inputs, iType='pt'):#pt, eta, phi, m): 264 | if iType == 'pt': 265 | self.pt, self.eta, self.phi, self.m = inputs 266 | self.initializePx() 267 | elif iType == 'px': 268 | self.px, self.py, self.pz, self.E = inputs 269 | self.initializePt() 270 | 271 | def initializePx(self): 272 | from math import sqrt, sin, cos, cosh 273 | self.E = self.pt * cosh(self.eta) 274 | self.px = self.pt * cos(self.phi) 275 | self.py = self.pt * sin(self.phi) 276 | self.pz = sqrt((E**2 - self.m**2 - self.pt**2)) 277 | 278 | def initializePt(self): 279 | from math import sqrt, atan2, tan, log 280 | 281 | self.pt = sqrt(self.px**2 + self.py**2) 282 | self.eta = -1 * log(tan(atan2(self.pt, self.pz)/2)) 283 | self.phi = atan2(self.py, self.px) 284 | self.m = sqrt(self.E**2 - self.pz**2 - self.pt**2) 285 | print self.pt, self.eta, self.phi, self.m 286 | 287 | def mass(self): 288 | return self.m 289 | 290 | def p(self): 291 | from math import sqrt 292 | return sqrt(self.pt**2 + self.pz**2) 293 | 294 | def pt(self): 295 | return self.pt 296 | 297 | def __add__(self, other): 298 | sumVec = [getattr(self, dd) + getattr(other, dd) for dd in ['px', 'py', 'pz', 'E']] 299 | print 'Sum pxpypzE is:', sumVec 300 | return self.__class__(sumVec, iType='px') 301 | 302 | def pairCorr(allRecords): 303 | from itertools import combinations 304 | import ROOT as rt 305 | 306 | pdfs = {} 307 | names = [('m', 'f8'), ('pt', 'f8'), ('dr', 'f8'), 308 | ('phi', 'f8'), ('cosT', 'f8'), ('p', 'f8'), 309 | ('nParts','i4'), ('isQCD', 'i4')] 310 | 311 | records = allRecords[allRecords['nParts'] == 20] 312 | nPartss = records['nParts'] 313 | nPairs = np.sum((nPartss * (nPartss -1 ))/2) 314 | pairVals = np.zeros(nPairs, dtype=names) 315 | iTrk = 0 316 | for iRec, rec in enumerate(records): 317 | # if iRec >= 1000: 318 | # break 319 | aids = rec['parts']['pdgId'] 320 | #charged = np.any([aids == 211, aids==321, aids==2212, 321 | # aids==11, aids==13] , axis=0) 322 | #for trackPair in combinations(rec['parts'][charged], 2): 323 | for trackPair in combinations(rec['parts'], 2): 324 | vecLi = [] 325 | for track in trackPair: 326 | mass = 0 327 | vec = rt.TLorentzVector() 328 | vec.SetPtEtaPhiM(track[1], track[2], track[3], mass) 329 | vecLi.append(vec) 330 | 331 | combVec = vecLi[0] + vecLi[1] 332 | # bVec = rt.TLorentzVector(vecLi[0]) 333 | # bVec.Boost( -combVec.BoostVector()) 334 | 335 | pairVals[iTrk]['isQCD'] = rec['pdgIDHardParton'] != 24 336 | pairVals[iTrk]['nParts'] = rec['nParts'] 337 | pairVals[iTrk]['m' ] = combVec.M() 338 | pairVals[iTrk]['pt'] = combVec.Pt()/rec['pt'] 339 | pairVals[iTrk]['p' ] = combVec.P()/(rec['pt']*math.cosh(rec['eta'])) 340 | pairVals[iTrk]['dr'] = vecLi[0].DeltaR(vecLi[1]) 341 | # pairVals[iTrk]['phi'] = math.atan2(bVec.Py(),bVec.Px()) 342 | # pairVals[iTrk]['cosT'] = bVec.Pz()/math.sqrt(bVec.Pt()**2 + bVec.Pz()**2) 343 | 344 | if np.any([np.isnan(pairVals[iTrk]['phi']), \ 345 | np.isnan(pairVals[iTrk]['cosT'])]): 346 | print 'Found NAN... dropping whole pair in', iRec 347 | iTrk -= 1 348 | 349 | 350 | iTrk += 1 351 | pairVals = pairVals[pairVals['nParts'] != 0] 352 | return pairVals 353 | 354 | def drawCorr(pairVals): 355 | import scipy.stats as sta 356 | 357 | nBins = 20 358 | edges = {'m': [], 'dr': [], 'pt': []} 359 | for kk in edges: 360 | edges[kk] = [sta.scoreatpercentile(pairVals[kk], ii * 100.0/nBins) 361 | for ii in range(nBins + 1)] 362 | 363 | 364 | cut = pairVals['isGluon'] == 1 365 | H, xedges, yedges = np.histogram2d( pairVals['m'][cut], pairVals[cut]['dr'], 366 | bins=[edges['m'], edges['dr']] 367 | ) 368 | preAspect = (yedges[-1] - yedges[0])/(xedges[-1] - xedges[0]) 369 | aspect = 1.2/preAspect 370 | 371 | extent = [yedges[0], yedges[-1], xedges[0], xedges[-1]] 372 | plt.imshow(H, extent=extent, aspect=aspect, interpolation='nearest', origin='lower') 373 | plt.xticks(xedges) 374 | plt.yticks(yedges) 375 | plt.show() 376 | 377 | def scaledTicks(edges): 378 | 379 | nBins = len(edges) - 1 380 | rng = edges[-1] - edges[0] 381 | low = edges[0] 382 | locs = [float(ii)*rng/nBins + low for ii in range(nBins + 1)] 383 | names = ['%.2f' % xx for xx in edges] 384 | 385 | return locs, names 386 | 387 | def corr_stuff(): 388 | # records = np.load(open(sys.argv[1])) 389 | pp = PdfPages('pairCorr.pdf') 390 | wrec = np.load(open('/u/eb/joshgc/mynfs/wjets.npy')) 391 | grec = np.load(open('/u/eb/joshgc/mynfs/gjets.npy')) 392 | 393 | wPairVals = pairCorr(wrec) 394 | gPairVals = pairCorr(grec) 395 | 396 | #drawCorr(pairVals) 397 | 398 | import scipy.stats as sta 399 | 400 | nBins2 = 20 401 | nBins1 = 100 402 | names = {'m' : 'Pair Mass (GeV)', 403 | 'dr' : 'Pair $\\Delta R$', 404 | 'pt' : 'Pair Sum Fractional $p_{T}$', 405 | 'p' : 'Pair Sum Fractional $p$', 406 | 'phi' : 'Decay Angle $\\phi$', 407 | 'cosT': 'Decay Angle $Cos \\theta$', 408 | } 409 | edges2 = dict((kk, []) for kk in names.keys()) 410 | edges1 = dict((kk, []) for kk in names.keys()) 411 | drawsToDo =[ ('m', 'dr'), ('m', 'pt'), ('pt', 'dr'), 412 | ('m', 'p'), ('p', 'dr'), 413 | #('m','phi'), ('m', 'cosT'), ('phi', 'cosT'), 414 | ] 415 | 416 | for kk in edges1: 417 | edges2[kk] = [sta.scoreatpercentile(wPairVals[kk], ii * 100.0/nBins2) 418 | for ii in range(nBins2 + 1)] 419 | edges1[kk] = [edges2[kk][0] + (edges2[kk][-1]-edges2[kk][0])*ii/nBins1 420 | for ii in range(nBins1+1)] 421 | 422 | print 'Edges are', edges2 423 | print 'Edges are', edges1 424 | for xKey in ['m', 'dr', 'pt', 'p']: 425 | Hw, xedges = np.histogram(wPairVals[xKey], bins=edges1[xKey]) 426 | Hg, xedges = np.histogram(gPairVals[xKey], bins=edges1[xKey]) 427 | Hw = np.maximum(Hw, .1) 428 | Hg = np.maximum(Hg, .1) 429 | Hw /= np.sum(Hw) 430 | Hg /= np.sum(Hg) 431 | bins = (xedges[:-1] + xedges[1:])/2 432 | plt.semilogy(bins, Hw, 'b', nonposy='clip', linewidth=5, label='W-Jets') 433 | plt.semilogy(bins, Hg, 'r', nonposy='clip', linewidth=5, label='G-Jets') 434 | plt.legend() 435 | plt.ylabel('Probability') 436 | plt.xlabel(names[xKey]) 437 | plt.savefig(pp, format='pdf') 438 | plt.clf() 439 | 440 | 441 | for xKey, yKey in drawsToDo: 442 | pdfs = {} 443 | H, xedges, yedges = np.histogram2d( wPairVals[xKey], wPairVals[yKey], 444 | bins=[edges2[xKey], edges2[yKey]] 445 | ) 446 | yTickLoc, yTickNames = scaledTicks(yedges) 447 | xTickLoc, xTickNames = scaledTicks(xedges) 448 | 449 | for doQCD in [0, 1]: 450 | pv = gPairVals if doQCD else wPairVals 451 | 452 | H, xedges, yedges = np.histogram2d( pv[xKey], pv[yKey], 453 | bins=[edges2[xKey], edges2[yKey]], 454 | ) 455 | H /= np.sum(H) 456 | preAspect = (xedges[-1] - xedges[0])/(yedges[-1] - yedges[0]) 457 | aspect = preAspect/1.2 458 | 459 | extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]] 460 | pdfs[doQCD] = H 461 | plt.imshow(H.T, extent=extent, aspect=aspect, interpolation='nearest', origin='lower') 462 | 463 | plt.xticks( xTickLoc, xTickNames, rotation=45) 464 | plt.yticks( yTickLoc, yTickNames) 465 | plt.ylabel(names[yKey]) 466 | plt.xlabel(names[xKey]) 467 | plt.colorbar() 468 | 469 | plt.title('Q/G' if doQCD == 1 else 'W') 470 | plt.savefig(pp, format='pdf') 471 | plt.clf() 472 | 473 | plt.imshow((pdfs[1] - pdfs[0]).T, extent=extent, aspect=aspect, 474 | interpolation='nearest', origin='lower') 475 | plt.xticks( xTickLoc, xTickNames, rotation=45) 476 | plt.yticks( yTickLoc, yTickNames) 477 | plt.ylabel(names[yKey]) 478 | plt.xlabel(names[xKey]) 479 | plt.colorbar() 480 | plt.title('P(g/q) - P(W)') 481 | plt.savefig(pp, format='pdf') 482 | plt.clf() 483 | 484 | plt.imshow(((pdfs[1] - pdfs[0])/(pdfs[1]+pdfs[0])).T, extent=extent, aspect=aspect, 485 | interpolation='nearest', origin='lower') 486 | plt.xticks( xTickLoc, xTickNames, rotation=45) 487 | plt.yticks( yTickLoc, yTickNames) 488 | plt.ylabel(names[yKey]) 489 | plt.xlabel(names[xKey]) 490 | plt.colorbar() 491 | plt.title('P(g/q) - P(W) / P(g/q) + P(W)') 492 | plt.savefig(pp, format='pdf') 493 | plt.clf() 494 | 495 | plt.imshow((pdfs[0]/pdfs[1]).T, extent=extent, aspect=aspect, 496 | interpolation='nearest', origin='lower') 497 | plt.xticks( xTickLoc, xTickNames, rotation=45) 498 | plt.yticks( yTickLoc, yTickNames) 499 | plt.ylabel(names[yKey]) 500 | plt.xlabel(names[xKey]) 501 | plt.colorbar() 502 | plt.title('P(W)/P(g/q)') 503 | plt.savefig(pp, format='pdf') 504 | plt.clf() 505 | 506 | pp.close() 507 | sys.exit(0) 508 | 509 | if __name__ == '__main__': 510 | from matplotlib.backends.backend_pdf import PdfPages 511 | 512 | incoming = ic.InputCleanerGen(sys.argv[1:], sys.stdin, search=r'^#G(.*)$', repl=r'\1') 513 | # low, high = 25, 26 514 | # print 'Beginning group production' 515 | # recGroups = makeGroups(sys.argv[1:], low, high) 516 | # 517 | pp = PdfPages('ed.caloJets.pdf') 518 | makeNCaloImages(pp, [rr for rr in incoming.getGen(15)]) 519 | # cuts = [] 520 | # fTrue = lambda xx: True 521 | # for ii in range(low, high): 522 | # 523 | # cuts.append(['W-Jets with %d Particles' % ii, 'w', ii, None]) 524 | # cuts.append(['Gluon Jets with %d Particles' % ii, 'g', ii, None]) 525 | # 526 | # for title, flavor, nParts, cutFunc in cuts: 527 | # print 'Working on', title 528 | ## print len(recGroups[flavor][nParts]) 529 | ## makeNImages(pp, recGroups[flavor][nParts], title, None, doBoost=False) 530 | # print len(recGroups[flavor]) 531 | # makeNImages(pp, recGroups[flavor], title, None, doBoost=False) 532 | 533 | pp.close() 534 | -------------------------------------------------------------------------------- /pyrootmagic.py: -------------------------------------------------------------------------------- 1 | # 2 | # $Id: pyrootmagic.py 340230 2013-10-15 00:37:57Z jcogan $ 3 | # 4 | '''Make adding branches work in PyROOT for vectors and scalars 5 | This code is experts only''' 6 | 7 | __author__ = "Josh Cogan (jcogan@cern.ch), Emanuel Strauss (estrauss@slac.stanford.edu)" 8 | __version__ = '$Revision: 340230 $' 9 | __date__ = '$Date: 2013-10-15 02:37:57 +0200 (Tue, 15 Oct 2013) $' 10 | 11 | import os 12 | try: 13 | import simpleLogging 14 | scribe = simpleLogging.getChildLogger('main', __name__) 15 | except ImportError: 16 | import logging 17 | scribe = logging.getLogger(__name__) 18 | 19 | typeMap = { 'O': ('bool' , False ) 20 | , 'I': ('int' , -999 ) 21 | , 'i': ('unsigned int' , 999 ) 22 | , 'S': ('short' , -999 ) 23 | , 's': ('unsigned short', 999 ) 24 | , 'D': ('double' , -999 ) 25 | , 'F': ('float' , -999 ) 26 | } 27 | 28 | 29 | 30 | ### ITS VERY IMPORTANT THAT THESE MATCH ROOT DOCUMENTATION 31 | typeRegexs = [ 32 | (r'(unsigned\s+int|UInt_t)' , 'i'), 33 | (r'(int|Int_t)' , 'I'), 34 | (r'(bool|Bool_t)' , 'O'), 35 | (r'(short|Short_t)' , 'S'), 36 | (r'(unsigned\s+short|UShort_t)' , 's'), 37 | (r'(float|Float_t)' , 'F'), 38 | (r'(double|Double_t)' , 'D'), 39 | ] 40 | 41 | _namesTaken = set() 42 | _nameConversions = [( 43 | ('smart_el', 'smart_el'), 44 | ('el_GSF' , 'smart_el'), 45 | ('el_gsf' , 'smart_el'), 46 | ('el' , 'smart_el'), 47 | ), 48 | ( # this is a group of mutually exlusive redefs 49 | ('smart_jet' , 'smart_jet'), 50 | ('jet_AntiKt4TopoEMJets' , 'smart_jet'), 51 | ('jet_akt4topoem' , 'smart_jet'), 52 | ('jet_AntiKt4TopoEM' , 'smart_jet'), 53 | ), 54 | ( 55 | ('smart_mu' , 'smart_mu'), 56 | ('mu_staco' , 'smart_mu'), 57 | ('mu' , 'smart_mu'), 58 | ) 59 | ] 60 | 61 | ## Generate the output tree code 62 | def makeStructString(varNames, sname = "MyStruct"): 63 | '''Produce the ROOT/C code defining all the variables to be filled''' 64 | defs = [] 65 | inits = [] 66 | for var, varDesc in varNames: 67 | cType = typeMap[varDesc.split(':')[0]][0] 68 | 69 | if ':' not in varDesc: 70 | line = '%s %s' % (cType, var) 71 | else: 72 | continue 73 | 74 | defs.append(line) 75 | 76 | s = "struct %s{\n\t" % sname 77 | s += ';\n\t'.join(defs) 78 | s += ';\n};\n' 79 | 80 | if len(inits) > 0: 81 | s += ';\n'.join(inits) + ';' 82 | 83 | return s 84 | 85 | def typeLookUp(inTree, branch): 86 | import re 87 | 88 | ll = inTree.GetLeaf(branch) 89 | if ll is None: 90 | return None 91 | 92 | try: 93 | sdesc = ll.GetTypeName() 94 | except ReferenceError: 95 | scribe.error('RefError') 96 | return None 97 | 98 | #need to make this nVector 99 | nVectors = len(re.findall(r'vector\s*<', sdesc)) 100 | for regStr, retVal in typeRegexs: 101 | if re.search(regStr, sdesc) is not None: 102 | return retVal + (':' * nVectors) 103 | 104 | scribe.error('%s %s failed' % branch, sdesc) 105 | return None 106 | 107 | def inputTreeVars(inTree): 108 | try: 109 | branches = [xx.GetName() for xx in inTree.GetListOfBranches()] 110 | except TypeError as ee: 111 | scribe.critical("inTree, %s, has no braches" % str(inTree)) 112 | raise ee 113 | 114 | branches = filter(lambda br: inTree.GetBranchStatus(br), branches) 115 | thisTreesNames = set(branches) 116 | 117 | #branches = doConversions(branches, thisTreesNames) 118 | newNameMap = {} 119 | for exclusiveGroup in _nameConversions: 120 | for prefix, unifiedName in exclusiveGroup: 121 | matchingBranches = [br for br in thisTreesNames if br.startswith(prefix)] 122 | if len(matchingBranches) < 10: 123 | #no branches match el_GSF, its okay to check el_vanilla 124 | #if just one branch does match el_GSF stop trying to match 125 | #ignore the few straggling matches, look for a block 126 | continue 127 | 128 | for mbr in matchingBranches: 129 | oldType = typeLookUp(inTree, mbr) 130 | if oldType is None: 131 | scribe.warning('Couldnt ascertain type of %s. Skipping it!' % mbr) 132 | continue 133 | 134 | newNameMap[mbr] = (unifiedName + mbr[len(prefix):], oldType) 135 | 136 | #since a branch matched el_GSF and got mapped to smart_el 137 | #don't allow any el_vanilla branches to also get mapped to smart_el 138 | break 139 | 140 | remappedVars = set(newNameMap.keys()) 141 | for br in thisTreesNames: 142 | if br in remappedVars: 143 | continue 144 | brType = typeLookUp(inTree, br) 145 | if brType is None: 146 | scribe.warning('Couldnt ascertain type of %s. Skipping it!' % br) 147 | else: 148 | newNameMap[br] = (br, brType) 149 | 150 | return newNameMap 151 | 152 | def bindInputToStruct(inTree, structObj, inTreeVars, tempDir='./'): 153 | import ROOT as rt 154 | ## this might not be necessary!! 155 | ## grep GenerateDictionary main_analysis.py 156 | loaderText ='''// File loader.C 157 | #include 158 | #ifdef __MAKECINT__ 159 | #pragma link C++ class vector >+; 160 | #pragma link C++ class vector >+; 161 | #pragma link C++ class vector >+; 162 | #pragma link C++ class vector >+; 163 | #endif 164 | ''' 165 | 166 | fLoc = os.path.join(tempDir, 'prmLoader.C') 167 | open(fLoc, 'w').write(loaderText) 168 | rt.gROOT.ProcessLine('.L %s+'% fLoc) 169 | 170 | branches = [] 171 | for oldName in inTreeVars: 172 | var, varDesc = inTreeVars[oldName] 173 | inBranch = inTree.GetBranch(oldName) 174 | 175 | if ':' in varDesc: 176 | inTree.SetBranchAddress(oldName, getattr(structObj, var)) 177 | pass 178 | else: 179 | inTree.SetBranchAddress(oldName, rt.AddressOf(structObj, var)) 180 | pass 181 | 182 | def getAndLoadStruct(varNames, inTree=None, force_recompile=False, sname="MyStruct"): 183 | ''' Produce a python object (struct) correctly interfaced with ROOT''' 184 | 185 | #force_recompile = True 186 | import subprocess 187 | import ROOT as rt 188 | import shutil 189 | import os.path 190 | import tempfile 191 | 192 | 193 | inTreeVars = {} 194 | if inTree is not None: 195 | inTreeVars = inputTreeVars(inTree) 196 | 197 | allVarNames = varNames + inTreeVars.values() 198 | 199 | if force_recompile: 200 | tempDirName = tempfile.mkdtemp('_pyrootmagic') 201 | else: 202 | ##appears ROOT can't load files name ./blah.so only blah.so 203 | tempDirName = os.getcwd() 204 | 205 | fileBase = os.path.join(tempDirName, 'structCode') 206 | 207 | s = '#include \n%s\n' % makeStructString(allVarNames, sname) 208 | f = open(fileBase+'.h', "w") 209 | f.write(s) 210 | f.close() 211 | 212 | # ARA uses cintex, which uses reflex, which clashes with the 213 | # vector dictionaries that are made with LoadMacro 214 | # Gaaah! 215 | #if True: 216 | gccXMLPath='--gccxmlpath='+os.path.expanduser('~joshgc/public/cern_style_gccxml/i686-slc5-gcc43-opt/bin') 217 | 218 | scribe.debug("Forcing recompile? %s" % force_recompile) 219 | scribe.debug("Shared object exists? %s" % os.path.exists(fileBase+'.so')) 220 | if not os.path.exists(fileBase+'.so') or force_recompile: 221 | scribe.warning('Need to rerun struct compilation on %s' % fileBase) 222 | subprocess.call("genreflex %s.h -o %s.cc -I $ROOTSYS/include --debug=1 %s" 223 | % (fileBase, fileBase, gccXMLPath), shell=True) 224 | subprocess.call(("g++ %s.h %s.cc -o %s.so `root-config --cflags --libs`" 225 | " -lReflex -lCintex -shared") 226 | % (fileBase, fileBase, fileBase), shell=True) 227 | else: 228 | scribe.warning('Skipping struct compilation') 229 | 230 | 231 | import PyCintex 232 | PyCintex.Cintex.Enable() 233 | rt.gSystem.Load(fileBase+'.so') 234 | 235 | structObj = getattr(rt, sname)() 236 | structObj.__dict__['_branches'] = list(allVarNames) 237 | 238 | # TBranch changes the vectors in the struct, so we use the hack below 239 | # Double Gaaah! 240 | for var, varDesc in allVarNames: 241 | if ':' in varDesc: 242 | cls = typeMap[varDesc.split(':')[0]][0] 243 | for ii in range(varDesc.count(':')): 244 | cls = rt.std.vector(cls) 245 | 246 | setattr(structObj, var, cls()) 247 | 248 | bindInputToStruct(inTree, structObj, inTreeVars, tempDirName) 249 | 250 | if force_recompile: 251 | try: 252 | shutil.rmtree(tempDirName) 253 | except OSError: 254 | scribe.error('Unable to delete temp directory %s' % tempDirName) 255 | scribe.error('This will be bad later on. Tell Josh.') 256 | 257 | 258 | return structObj, allVarNames 259 | 260 | def clearStruct(sObj): 261 | '''Set all the struct variables to their defaults. 262 | These are defined in the type map. 263 | ''' 264 | 265 | #do i have to handle the vector vector stuff here too? 266 | for var, varType in sObj._branches: 267 | if ':' in varType: 268 | getattr(sObj, var).clear() 269 | pass 270 | else: 271 | #this is probably slow, always go to 999? 272 | setattr(sObj, var, typeMap[varType.split(':')[0]][1]) 273 | 274 | 275 | def mapVariablesToBranches(vstruct, tree_out, listOfVars): 276 | import ROOT as rt 277 | for var, varDesc in listOfVars: 278 | cType = varDesc.split(':')[0] 279 | if ':' not in varDesc: 280 | tree_out.Branch(var, rt.AddressOf(vstruct, var), '%s/%s' % (var, cType)) 281 | pass 282 | else: 283 | tree_out.Branch(var, "vector<%s>" % typeMap[cType][0], getattr(vstruct, var)) 284 | pass 285 | pass #end of mapVariablesToBranches 286 | 287 | listOfVars =[ 288 | # Indices of Jets suriving overlap removal 289 | ('jet_index' , 'I:') 290 | # Indices for H->Z(ll)ph reconstruction 291 | # One per reconstruction 292 | , ('l1_index' , 'I:') 293 | , ('l2_index' , 'I:') 294 | , ('ph_index' , 'I:') 295 | 296 | # Event level variables for numbers of objects, indices for best candidates 297 | # One per event 298 | , ('n_ee' , 'I') 299 | , ('n_mm' , 'I') 300 | , ('n_jet' , 'I') 301 | , ('n_tau' , 'I') 302 | , ('best_ee_index' , 'I') 303 | , ('best_mm_index' , 'I') 304 | 305 | , ('truth_H_index' , 'I') 306 | , ('truth_Z_index' , 'I') 307 | , ('truth_ph_index' , 'I') 308 | , ('truth_l1_index' , 'I') 309 | , ('truth_l2_index' , 'I') 310 | 311 | # Branch for keep track of species of particle and best candidates 312 | # One per reconstruction 313 | , ('mode' , 'I:') 314 | 315 | #these appear to be never used in main_analysis. 316 | #Looks like is_best_Hee is preferred 317 | #, ('is_best_ee' , 'I:') 318 | #, ('is_best_mm' , 'I:') 319 | 320 | # Z(ll) and H(ll)ph kinematics 321 | # One per reconstruction 322 | , ('Z_pt' , 'D:') 323 | , ('Z_eta' , 'D:') 324 | , ('Z_phi' , 'D:') 325 | , ('Z_E' , 'D:') 326 | , ('Z_m' , 'D:') 327 | , ('H_pt' , 'D:') 328 | , ('H_eta' , 'D:') 329 | , ('H_phi' , 'D:') 330 | , ('H_E' , 'D:') 331 | , ('H_m' , 'D:') 332 | , ('H_cosCapTheta' , 'D:') 333 | , ('H_cosTheta' , 'D:') 334 | , ('H_cosBkgPhi' , 'D:') 335 | , ('H_truth_cosCapTheta', 'D:') 336 | , ('H_truth_cosTheta' , 'D:') 337 | , ('H_truth_cosBkgPhi' , 'D:') 338 | , ('H_pT_t' , 'D:') 339 | , ('H_category' , 'I:') 340 | 341 | , ('brem_none_Z_m' , 'D') 342 | , ('brem_none_H_m' , 'D') 343 | , ('brem_all_Z_m' , 'D') 344 | , ('brem_one_Z_m' , 'D') 345 | , ('brem_one_H_m' , 'D') 346 | , ('brem_clus_dr' , 'D') 347 | , ('brem_clus_pt' , 'D') 348 | , ('brem_clus_il' , 'I') 349 | , ('brem_pre_mu_eta' , 'D') 350 | , ('brem_pre_mu_pt' , 'D') 351 | 352 | , ('brem_mass_llhood' , 'D') 353 | , ('brem_ang_llhood' , 'D') 354 | , ('brem_llhood' , 'D') 355 | 356 | # DeltaR and DeltaPhi variables for H->Z(ll)ph reconstructions 357 | # One per reconstruction 358 | , ('l1l2_DR' , 'D:') 359 | , ('l1ph_DR' , 'D:') 360 | , ('l2ph_DR' , 'D:') 361 | , ('l1Z_DR' , 'D:') 362 | , ('l1H_DR' , 'D:') 363 | , ('l2Z_DR' , 'D:') 364 | , ('l2H_DR' , 'D:') 365 | , ('phZ_DR' , 'D:') 366 | , ('phH_DR' , 'D:') 367 | , ('ZH_DR' , 'D:') 368 | , ('l1l2_DPhi' , 'D:') 369 | , ('l1ph_DPhi' , 'D:') 370 | , ('l2ph_DPhi' , 'D:') 371 | , ('l1Z_DPhi' , 'D:') 372 | , ('l1H_DPhi' , 'D:') 373 | , ('l2Z_DPhi' , 'D:') 374 | , ('l2H_DPhi' , 'D:') 375 | , ('phZ_DPhi' , 'D:') 376 | , ('phH_DPhi' , 'D:') 377 | , ('ZH_DPhi' , 'D:') 378 | , ('ph_jet_DR' , 'D:') 379 | , ('ph_tau_DR' , 'D:') 380 | , ('ph_jet_index' , 'I:') 381 | , ('ph_tau_index' , 'I:') 382 | 383 | # Kinematic variables for objects so we don't have to look them up 384 | , ('l1_pt' , 'D:') 385 | , ('l1_eta' , 'D:') 386 | , ('l1_phi' , 'D:') 387 | , ('l1_E' , 'D:') 388 | , ('l1_charge' , 'D:') 389 | , ('l2_pt' , 'D:') 390 | , ('l2_eta' , 'D:') 391 | , ('l2_phi' , 'D:') 392 | , ('l2_E' , 'D:') 393 | , ('l2_charge' , 'D:') 394 | , ('H_ph_pt' , 'D:') 395 | , ('H_ph_eta' , 'D:') 396 | , ('H_ph_phi' , 'D:') 397 | , ('H_ph_E' , 'D:') 398 | 399 | , ('l1_etcone20' , 'D:') 400 | , ('l1_etcone30' , 'D:') 401 | , ('l1_etcone40' , 'D:') 402 | , ('l1_nucone20' , 'D:') 403 | , ('l1_nucone30' , 'D:') 404 | , ('l1_nucone40' , 'D:') 405 | , ('l1_ptcone20' , 'D:') 406 | , ('l1_ptcone30' , 'D:') 407 | , ('l1_ptcone40' , 'D:') 408 | , ('l2_etcone20' , 'D:') 409 | , ('l2_etcone30' , 'D:') 410 | , ('l2_etcone40' , 'D:') 411 | , ('l2_nucone20' , 'D:') 412 | , ('l2_nucone30' , 'D:') 413 | , ('l2_nucone40' , 'D:') 414 | , ('l2_ptcone20' , 'D:') 415 | , ('l2_ptcone30' , 'D:') 416 | , ('l2_ptcone40' , 'D:') 417 | , ('H_ph_etcone20' , 'D:') 418 | , ('H_ph_etcone30' , 'D:') 419 | , ('H_ph_etcone40' , 'D:') 420 | , ('H_ph_ptcone20' , 'D:') 421 | , ('H_ph_ptcone30' , 'D:') 422 | , ('H_ph_ptcone40' , 'D:') 423 | 424 | # Object tightness 425 | , ('l1_tightness' , 'I:') 426 | , ('l2_tightness' , 'I:') 427 | , ('ph_tightness' , 'I:') 428 | 429 | , ('is_best_Hee' , 'I:') 430 | , ('is_best_Hmm' , 'I:') 431 | 432 | # Auxiliary variables 433 | # One per reconstruction 434 | , ('l1ph_m' , 'D:') # Invariant mass of a lepton and the photon 435 | , ('l2ph_m' , 'D:') # Invariant mass of a lepton and the photon 436 | 437 | # Truthmatching 438 | # One per reconstruction 439 | # Keep these as ints, we may want to contain more information than a bool at some point 440 | # H->Z(ee)ph 441 | , ('real_l1' , 'I:') # =1 if the first electron candidate in a recontsruction is really an electron 442 | , ('real_l2' , 'I:') # =1 if the second electron candidate in a recontsruction is really an electron 443 | , ('real_ph' , 'I:') # =1 if the photon candidate in a recontsruction is really a photon 444 | , ('l1_from_Z' , 'I:') # =1 if the first electron is real and comes from a real Z 445 | , ('l2_from_Z' , 'I:') # =1 if the second electron is real and comes from a real Z 446 | , ('same_Z' , 'I:') # =1 if both electrons come from the same real Z 447 | , ('Z_from_H' , 'I:') # =1 if both electrons come from the same real Z and this Z comes from a real H 448 | , ('ph_from_H' , 'I:') # =1 if the photon comes from a real Higgs 449 | , ('same_H' , 'I:') # =1 if both electrons come from the same real Z, and that Z and the photon come from a real Higgs 450 | , ('ph_source' , 'I:') # integer (enum-esque) indicating genre of photon 451 | , ('ph_source_weight' , 'I:') # 0 if this photon is overlaps with sherpa ME calculation 452 | , ('ph_parent_index' , 'I:') # mc_index of parent of photon 453 | , ('ph_parent' , 'I:') # pdgId of parent of photon 454 | , ('ph_grandparent' , 'I:') # pdgId of parent of parent of photon 455 | 456 | # Weights 457 | # Some weights are reconstruction dependent 458 | , ('pileup_pass' , 'O' ) 459 | , ('pileup_weight' , 'D' ) 460 | , ('trigger_weight' , 'D' ) 461 | , ('crosssection_weight', 'D' ) 462 | , ('blind_weight' , 'D:') 463 | , ('weight' , 'D:') # Never used?? 464 | , ('SF' , 'D:') # Multiplicative scale factor 465 | 466 | # Definitions of objects 467 | , ('is_cutflow_1' , 'I:') 468 | , ('is_cutflow_2' , 'I:') 469 | , ('H_definition_bitmap' , 'I:') 470 | , ('l1_definition_bitmap', 'I:') 471 | , ('l2_definition_bitmap', 'I:') 472 | , ('ph_definition_bitmap', 'I:') 473 | ] 474 | 475 | for lepType in ('both', 'only_ph', 'only_el'): 476 | for clusMin in ('1000', '3500'): 477 | for vv in ('clus_pt', 'clus_dr', 'clus_il', 'one_Z_m', 'one_H_m'): 478 | listOfVars.append(('brem_%s_%s_%s' % (vv, lepType, clusMin), 'D')) 479 | 480 | if __name__ == '__main__': 481 | import ROOT as rt 482 | 483 | inChain = rt.TChain("physics") 484 | inChain.Add("~arconde/dq2/HToZGamma/mc11_7TeV.128988.PowHegPythia_ggH125_Zgam_Zmumu.merge.NTUP_HSG2.e1063_s1372_s1370_r3043_r2993_p869_tid729809_00/*") 485 | #inChain.Add("output/skimmed/data11_7TeV_177986_physics_Egamma_r2603_p659_p761_p762.root") 486 | inChain.SetBranchStatus("*", 0) 487 | inChain.SetBranchStatus("mc_*", 1) 488 | #inChain.SetBranchStatus("el_*n", 1) 489 | #inChain.SetBranchStatus("el_*loose", 1) 490 | #inChain.SetBranchStatus("el_*eta", 1) 491 | 492 | ff = rt.TFile('output.root', 'recreate') 493 | tt = rt.TTree('arg', 'arg') 494 | 495 | vstruct, newListOfVars = getAndLoadStruct([], inChain) 496 | #vstruct, newListOfVars = getAndLoadStruct(listOfVars, inChain) 497 | 498 | mapVariablesToBranches(vstruct, tt, newListOfVars) 499 | for ii in range(5): 500 | clearStruct(vstruct) 501 | inChain.GetEntry(ii) 502 | print 'Entry %d ---------------------' % ii 503 | print 'direct', inChain.mc_n, inChain.mc_parents.size(),inChain.mc_parents[0].size() 504 | print 'struct', vstruct.mc_n, inChain.mc_parents.size(),inChain.mc_parents[0].size() 505 | print 'Calling destructors!' 506 | --------------------------------------------------------------------------------