Skip to content

Commit

Permalink
Adding the hit firmware
Browse files Browse the repository at this point in the history
  • Loading branch information
rodwyer100 committed Sep 20, 2024
1 parent 892b19f commit 68bfbc0
Show file tree
Hide file tree
Showing 9 changed files with 1,006 additions and 1 deletion.
178 changes: 178 additions & 0 deletions TrigScint/exampleConfigs/firmwareEx2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
#!/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

from LDMX.TrigScint.trigScint import TrigScintFirmwareHitProducer
from LDMX.TrigScint.trigScint import TrigScintQIEDigiProducer
from LDMX.TrigScint.trigScint import TrigScintRecHitProducer

qieDigi = TrigScintQIEDigiProducer.pad3()
rechit = TrigScintRecHitProducer.pad3()
hitFirm = TrigScintFirmwareHitProducer( "hitFirm" )



# # 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, qieDigi, rechit, hitFirm]
# 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)
11 changes: 11 additions & 0 deletions TrigScint/include/TrigScint/Firmware/hitproducer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef HITPRODUCER_H
#define HITPRODUCER_H

#include "objdef.h"

void copyHit1(Hit One, Hit Two);
void copyHit2(Hit One, Hit Two);
void hitproducer_ref(ap_uint<14> FIFO[NHITS][5],Hit outHit[NHITS],ap_uint<8> Peds[NHITS]);
void hitproducer_hw(ap_uint<14> FIFO[NHITS][5],Hit outHit[NHITS],ap_uint<8> Peds[NHITS]);

#endif
2 changes: 1 addition & 1 deletion TrigScint/include/TrigScint/Firmware/objdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include "ap_int.h"
#define NTIMES 6
#define NHITS 25
#define NHITS 50
#define NCLUS 25
#define NCHAN 50
#define NTRK 10
Expand Down
130 changes: 130 additions & 0 deletions TrigScint/include/TrigScint/NumericalRecHitProducer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/**
* @file NumericalRecHitProducer.h
* @brief Class that builds recHits
* @author Andrew Whitbeck, TTU
*/

#ifndef TRIGSCINT_TRIGSCINTDIGIPRODUCER_H
#define TRIGSCINT_TRIGSCINTDIGIPRODUCER_H

/*~~~~~~~~~~*/
/* ROOT */
/*~~~~~~~~~~*/
#include "TRandom3.h"
#include "TVectorD.h"

// LDMX
#include "DetDescr/TrigScintID.h"
#include "Recon/Event/EventConstants.h"
#include "Tools/NoiseGenerator.h"
#include "TrigScint/Event/TrigScintHit.h"
#include "TrigScint/Event/TrigScintQIEDigis.h"

/*~~~~~~~~~~~~~~~*/
/* Framework */
/*~~~~~~~~~~~~~~~*/
#include "Framework/Configure/Parameters.h"
#include "Framework/EventProcessor.h"

/*~~~~~~~~~~~*/
/* TrigScint */
/*~~~~~~~~~~~*/
#include "TrigScint/SimQIE.h"

namespace trigscint {

/**
* @class NumericalRecHitProducer
* @brief Organizes digis into TrigScintHits, linearizes TDC
* and ADC info, and converts amplitudes to PEs
*/
class NumericalRecHitProducer : public framework::Producer {
public:
NumericalRecHitProducer(const std::string& name, framework::Process& process);

~NumericalRecHitProducer();

/**
* Callback for the processor to configure itself from the given set
* of parameters.
*
* @param parameters ParameterSet for configuration.
*/
void configure(framework::config::Parameters& parameters) final override;

void produce(framework::Event& event);

/**
* Const function for pulse fitting
* @param params an array of 2 elements specifying
* pulse arrival time and pulse amplitude (Total integral)
*/
double CostFunction(const double* params);

/// QIE Sampling frequency (in MHz)
float qie_sf_{40.};

private:
/**
* Reconstruct true charge deposited in each time sample
* @param adc array of adcs for give event, cell
* @param tdc array of tdcs for give event, cell
* @param sample sample of interest
*/
Double_t ChargeReconstruction(std::vector<int>adc
,std::vector<int>tdc
,int sample=2);

/// Linearized charge. (Will be updated every time sample)
double Qm{0};

/// Time of crossing tdc threshold (Will be updated every time sample)
double tm{0};

/// QIE TDC Current threshold
float tdc_thr_;

/// Class to set the verbosity level.
// TODO: Make use of the global verbose parameter.
bool verbose_{false};

/// Name of the input collection containing the sim hits
std::string inputCollection_;

/// Name of the pass that the input collection is on (empty string means take
/// any pass)
std::string inputPassName_;

/// Name of the output collection that will be used to stored the
/// digitized trigger scintillator hits
std::string outputCollection_;

/// SiPM gain
double gain_{1e6};

/// QIE pedestal
double pedestal_{6.0};

/// QIE pedestal
double noise_{1.5};

/// Total MeV per MIP
double mevPerMip_{1.40};

/// Total number of photoelectrons per MIP
double pePerMip_{13.5};

/// Sample of interest
int sample_of_interest_{2};

/// Input pulse shape for fitting
std::string input_pulse_shape_;

/// Input pulse parameters for fitting
std::vector<float> pulse_params_;
};

} // namespace trigscint

#endif
Loading

0 comments on commit 68bfbc0

Please sign in to comment.