Skip to content

Commit

Permalink
Implementation of TS clustering and tracking as envisioned in LUT fir…
Browse files Browse the repository at this point in the history
…mware. (#1461)

* First commit of firmware changes

* First commit of firmware changes

* Update TrigScint/include/TrigScint/TrigScintFirmwareTracker.h

Co-authored-by: Tamas Vami <tamas.almos.vami@cern.ch>

* Update TrigScint/src/TrigScint/TrigScintFirmwareTracker.cxx

Co-authored-by: Tamas Vami <tamas.almos.vami@cern.ch>

* Update TrigScint/exampleConfigs/firmwareEx.py

Co-authored-by: Tamas Vami <tamas.almos.vami@cern.ch>

* Update TrigScint/exampleConfigs/firmwareEx.py

Co-authored-by: Tamas Vami <tamas.almos.vami@cern.ch>

* Commiting removal of print out statements

* Commiting removal of superfluous firmware ap int libraries

* Commiting removal of hard coded channel numbers

* Forgot to add some changes that we unstagged w.r.t. the comments and CMakeFix. I haven't included all of the class name changes (capitalizations) I may eventually include

* Committed smart pointer (for real this time).

* Cleaning firmware objects to align with capitalization scheme

* A few more things

* Trying to do clang fixes

* Reverting to old ldmx-env.sh

* Changing to array structure, haven't validated this yes please don't push just now.

* Apply clang-format

* yay! all done

* Apply clang-format

Attempts were made to use std::array instead of passing around bare pointers. There are some C-style fixed length arrays (T arr[N]) mixed with STL fixed-length arrays (std::array<T,N>) but we have avoided spurious `new` floating around.

---------

Co-authored-by: rodwyer@stanford.edu <rodwyer1@sdfiana006.sdf.slac.stanford.edu>
Co-authored-by: Tamas Vami <tamas.almos.vami@cern.ch>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
4 people committed Sep 20, 2024
1 parent c1164a4 commit 6c08a49
Show file tree
Hide file tree
Showing 12 changed files with 1,217 additions and 1 deletion.
4 changes: 3 additions & 1 deletion TrigScint/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@ if(BUILD_EVENT_ONLY)

endif()

setup_library(module TrigScint name Firmware)
target_include_directories(TrigScint_Firmware PUBLIC ../Trigger/HLS_arbitrary_Precision_Types/include)
setup_library(module TrigScint
dependencies Framework::Framework Recon::Event DetDescr::DetDescr
Tools::Tools SimCore::Event
Tools::Tools SimCore::Event TrigScint::Firmware
)

setup_python(package_name LDMX/TrigScint)

168 changes: 168 additions & 0 deletions TrigScint/exampleConfigs/firmwareEx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#!/bin/python

import sys
import os
import json

# we need the ldmx configuration package to construct the object

from LDMX.Framework import ldmxcfg

# set a 'pass name'
passName="sim"
p=ldmxcfg.Process(passName)

#import all processors
from LDMX.SimCore import generators
from LDMX.SimCore import simulator
from LDMX.Biasing import filters

from LDMX.Detectors.makePath import *
from LDMX.SimCore import simcfg

#pull in command line options
nEle=4 # simulated beam electrons
runNum=10
version="ldmx-det-v14"
outputNameString= "ldmxdetv14gap10mm_firmware.root" #sample identifier
outDir= "" #sample identifier

#
# Instantiate the simulator.
#
sim = simulator.simulator("test")

#
# Set the path to the detector to use (pulled from job config)
#
sim.setDetector( version, True )
sim.scoringPlanes = makeScoringPlanesPath(version)

outname=outputNameString #+".root"
print("NAME = " + outname)

#
# Set run parameters. These are all pulled from the job config
#
p.run = runNum
p.maxEvents = 100
nElectrons = nEle
beamEnergy = 4.0; #in GeV

sim.description = "Inclusive "+str(beamEnergy)+" GeV electron events, "+str(nElectrons)+"e"
#sim.randomSeeds = [ SEED1 , SEED2 ]
sim.beamSpotSmear = [20., 80., 0]


mpgGen = generators.multi( "mgpGen" ) # this is the line that actually creates the generator
mpgGen.vertex = [ -44., 0., -880. ] # mm
mpgGen.nParticles = nElectrons
mpgGen.pdgID = 11
mpgGen.enablePoisson = False #True

import math
theta = math.radians(5.45)
beamEnergyMeV=1000*beamEnergy
px = beamEnergyMeV*math.sin(theta)
py = 0.;
pz= beamEnergyMeV*math.cos(theta)
mpgGen.momentum = [ px, py, pz ]

#
# Set the multiparticle gun as generator
#
sim.generators = [ mpgGen ]

#reconstruction and vetoes

#Ecal and Hcal hardwired/geometry stuff
#import LDMX.Ecal.EcalGeometry
import LDMX.Ecal.ecal_hardcoded_conditions
from LDMX.Ecal import EcalGeometry
#egeom = EcalGeometry.EcalGeometryProvider.getInstance()
#Hcal hardwired/geometry stuff
from LDMX.Hcal import HcalGeometry
import LDMX.Hcal.hcal_hardcoded_conditions
#hgeom = HcalGeometry.HcalGeometryProvider.getInstance()


from LDMX.Ecal import digi as eDigi
from LDMX.Ecal import vetos
from LDMX.Hcal import digi as hDigi
from LDMX.Hcal import hcal

from LDMX.Recon.simpleTrigger import TriggerProcessor

from LDMX.TrigScint.trigScint import TrigScintDigiProducer
from LDMX.TrigScint.trigScint import TrigScintClusterProducer
from LDMX.TrigScint.trigScint import trigScintTrack
from LDMX.TrigScint.trigScint import TrigScintFirmwareTracker

tsSimColls=[ "TriggerPad2SimHits", "TriggerPad3SimHits", "TriggerPad1SimHits" ]

# ecal digi chain
# ecalDigi =eDigi.EcalDigiProducer('EcalDigis')
# ecalReco =eDigi.EcalRecProducer('ecalRecon')
# ecalVeto =vetos.EcalVetoProcessor('ecalVetoBDT')

# #hcal digi chain
# hcalDigi =hDigi.HcalDigiProducer('hcalDigis')
# hcalReco =hDigi.HcalRecProducer('hcalRecon')
# hcalVeto =hcal.HcalVetoProcessor('hcalVeto')
# #hcalDigi.inputCollName="HcalSimHits"
#hcalDigi.inputPassName=passName

# TS digi + clustering + track chain
tsDigisTag =TrigScintDigiProducer.pad2()
tsDigisTag.input_collection = tsSimColls[0]# +"_"+passName
tsDigisTag.input_pass_name = "sim"
tsDigisUp =TrigScintDigiProducer.pad3()
tsDigisUp.input_collection = tsSimColls[1]# +"_"+passName
tsDigisUp.input_pass_name = "sim"
tsDigisDown=TrigScintDigiProducer.pad1()
tsDigisDown.input_collection = tsSimColls[2]# +"_"+passName
tsDigisDown.input_pass_name = "sim"

tsClustersTag =TrigScintClusterProducer.pad2()
tsClustersUp =TrigScintClusterProducer.pad1()
tsClustersDown =TrigScintClusterProducer.pad3()


tsDigisUp.verbosity=0
tsClustersUp.verbosity=1
trigScintTrack.verbosity=1

trigScintTrack.delta_max = 0.75

trigFirm = TrigScintFirmwareTracker( "trigFirm" )
trigFirm.input_pass_name = "sim"
trigFirm.digis1_collection = "trigScintDigisPad1"
trigFirm.digis2_collection = "trigScintDigisPad2"
trigFirm.digis3_collection = "trigScintDigisPad3"
trigFirm.output_collection = "TriggerPadTracksFirmware"

from LDMX.Recon.electronCounter import ElectronCounter
eCount = ElectronCounter( nElectrons, "ElectronCounter") # first argument is number of electrons in simulation
eCount.use_simulated_electron_number = False
eCount.input_collection="TriggerPadTracks"
eCount.input_pass_name=passName

# # p.sequence=[ sim, ecalDigi, ecalReco, ecalVeto, hcalDigi, hcalReco, hcalVeto, tsDigisTag, tsDigisUp, tsDigisDown, tsClustersTag, tsClustersUp, tsClustersDown, trigScintTrack, eCount ]
# #hcal digi keeps crashing in config step
p.sequence=[ sim, tsDigisTag, tsDigisUp, tsDigisDown, tsClustersTag, tsClustersUp, tsClustersDown, trigScintTrack, trigFirm, eCount]
# p.sequence=[sim]

p.outputFiles=[outname]

p.termLogLevel = 0 # default is 2 (WARNING); but then logFrequency is ignored. level 1 = INFO.

#print this many events to stdout (independent on number of events, edge case: round-off effects when not divisible. so can go up by a factor 2 or so)
logEvents=20
if p.maxEvents < logEvents :
logEvents = p.maxEvents
p.logFrequency = int( p.maxEvents/logEvents )

#json.dumps(p.parameterDump(), indent=2)

with open('parameterDump.json', 'w') as outfile:
json.dump(p.parameterDump(), outfile, indent=4)
167 changes: 167 additions & 0 deletions TrigScint/exampleConfigs/meganEx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
#!/bin/python

import sys
import os
import json

# we need the ldmx configuration package to construct the object

from LDMX.Framework import ldmxcfg

# set a 'pass name'
passName="sim"
p=ldmxcfg.Process(passName)

#import all processors
from LDMX.SimCore import generators
from LDMX.SimCore import simulator
from LDMX.Biasing import filters

from LDMX.Detectors.makePath import *
from LDMX.SimCore import simcfg

#pull in command line options
nEle=4 # simulated beam electrons
runNum=10
version="ldmx-det-v14"
outputNameString= "ldmxdetv14gap10mm.root" #sample identifier
outDir= "" #sample identifier

#
# Instantiate the simulator.
#
sim = simulator.simulator("test")

#
# Set the path to the detector to use (pulled from job config)
#
sim.setDetector( version, True )
sim.scoringPlanes = makeScoringPlanesPath(version)

outname=outputNameString #+".root"
print("NAME = " + outname)

#
# Set run parameters. These are all pulled from the job config
#
p.run = runNum
p.maxEvents = 100
nElectrons = nEle
beamEnergy = 4.0; #in GeV

sim.description = "Inclusive "+str(beamEnergy)+" GeV electron events, "+str(nElectrons)+"e"
#sim.randomSeeds = [ SEED1 , SEED2 ]
sim.beamSpotSmear = [20., 80., 0]


mpgGen = generators.multi( "mgpGen" ) # this is the line that actually creates the generator
mpgGen.vertex = [ -44., 0., -880. ] # mm
mpgGen.nParticles = nElectrons
mpgGen.pdgID = 11
mpgGen.enablePoisson = False #True

import math
theta = math.radians(5.45)
beamEnergyMeV=1000*beamEnergy
px = beamEnergyMeV*math.sin(theta)
py = 0.;
pz= beamEnergyMeV*math.cos(theta)
mpgGen.momentum = [ px, py, pz ]

#
# Set the multiparticle gun as generator
#
sim.generators = [ mpgGen ]

#reconstruction and vetoes

#Ecal and Hcal hardwired/geometry stuff
#import LDMX.Ecal.EcalGeometry
import LDMX.Ecal.ecal_hardcoded_conditions
from LDMX.Ecal import EcalGeometry
#egeom = EcalGeometry.EcalGeometryProvider.getInstance()
#Hcal hardwired/geometry stuff
from LDMX.Hcal import HcalGeometry
import LDMX.Hcal.hcal_hardcoded_conditions
#hgeom = HcalGeometry.HcalGeometryProvider.getInstance()


from LDMX.Ecal import digi as eDigi
from LDMX.Ecal import vetos
from LDMX.Hcal import digi as hDigi
from LDMX.Hcal import hcal

from LDMX.Recon.simpleTrigger import TriggerProcessor

from LDMX.TrigScint.trigScint import TrigScintDigiProducer
from LDMX.TrigScint.trigScint import TrigScintClusterProducer
from LDMX.TrigScint.trigScint import trigScintTrack

if "v12" in version :
tsSimColls=[ "TriggerPadTagSimHits", "TriggerPadUpSimHits", "TriggerPadDnSimHits" ]
else :
tsSimColls=[ "TriggerPad2SimHits", "TriggerPad3SimHits", "TriggerPad1SimHits" ]

# ecal digi chain
# ecalDigi =eDigi.EcalDigiProducer('EcalDigis')
# ecalReco =eDigi.EcalRecProducer('ecalRecon')
# ecalVeto =vetos.EcalVetoProcessor('ecalVetoBDT')

# #hcal digi chain
# hcalDigi =hDigi.HcalDigiProducer('hcalDigis')
# hcalReco =hDigi.HcalRecProducer('hcalRecon')
# hcalVeto =hcal.HcalVetoProcessor('hcalVeto')
# #hcalDigi.inputCollName="HcalSimHits"
#hcalDigi.inputPassName=passName

# TS digi + clustering + track chain
tsDigisTag =TrigScintDigiProducer.pad2()
tsDigisTag.input_collection = tsSimColls[0]# +"_"+passName
tsDigisTag.input_pass_name = "sim"
tsDigisUp =TrigScintDigiProducer.pad3()
tsDigisUp.input_collection = tsSimColls[1]# +"_"+passName
tsDigisUp.input_pass_name = "sim"
tsDigisDown=TrigScintDigiProducer.pad1()
tsDigisDown.input_collection = tsSimColls[2]# +"_"+passName
tsDigisDown.input_pass_name = "sim"

tsClustersTag =TrigScintClusterProducer.pad2()
tsClustersUp =TrigScintClusterProducer.pad1()
tsClustersDown =TrigScintClusterProducer.pad3()

if "v12" in version :
tsClustersTag.pad_time = -2.
tsClustersUp.pad_time = 0.
tsClustersDown.pad_time = 0.

tsDigisUp.verbosity=0
tsClustersUp.verbosity=1
trigScintTrack.verbosity=1

trigScintTrack.delta_max = 0.75

from LDMX.Recon.electronCounter import ElectronCounter
eCount = ElectronCounter( nElectrons, "ElectronCounter") # first argument is number of electrons in simulation
eCount.use_simulated_electron_number = False
eCount.input_collection="TriggerPadTracks"
eCount.input_pass_name=passName

# # p.sequence=[ sim, ecalDigi, ecalReco, ecalVeto, hcalDigi, hcalReco, hcalVeto, tsDigisTag, tsDigisUp, tsDigisDown, tsClustersTag, tsClustersUp, tsClustersDown, trigScintTrack, eCount ]
# #hcal digi keeps crashing in config step
p.sequence=[ sim, tsDigisTag, tsDigisUp, tsDigisDown, tsClustersTag, tsClustersUp, tsClustersDown, trigScintTrack, eCount]
# p.sequence=[sim]

p.outputFiles=[outname]

p.termLogLevel = 0 # default is 2 (WARNING); but then logFrequency is ignored. level 1 = INFO.

#print this many events to stdout (independent on number of events, edge case: round-off effects when not divisible. so can go up by a factor 2 or so)
logEvents=20
if p.maxEvents < logEvents :
logEvents = p.maxEvents
p.logFrequency = int( p.maxEvents/logEvents )

json.dumps(p.parameterDump(), indent=2)

with open('parameterDump.json', 'w') as outfile:
json.dump(p.parameterDump(), outfile, indent=4)
12 changes: 12 additions & 0 deletions TrigScint/include/TrigScint/Firmware/clusterproducer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef CLUSTERPRODUCER_H
#define CLUSTERPRODUCER_H

#include "objdef.h"

void copyHit1(Hit One, Hit Two);
void copyHit2(Hit One, Hit Two);
void clusterproducer_ref(Hit inHit[NHITS], Cluster outClus[NCLUS]);
std::array<Cluster, NCLUS> clusterproducer_sw(Hit inHit[NHITS]);
void clusterproducer_hw(Hit inHit[NHITS], Cluster outClus[NCLUS]);

#endif
Loading

0 comments on commit 6c08a49

Please sign in to comment.