Skip to content
This repository has been archived by the owner on May 9, 2024. It is now read-only.

69 add the ability to time shift simhits before digitizing them #73

Open
wants to merge 10 commits into
base: trunk
Choose a base branch
from

Conversation

EinarElen
Copy link
Contributor

@EinarElen EinarElen commented Apr 1, 2024

This resolves LDMX-Software/ldmx-sw#1343 by adding the following options to the digitizer (primarily for TB stuff)

  • Apply a constant time shift to all events
  • Apply a configurable time shift per event/spill
  • Apply a configurable time shift per hit

The configurable shifts are

  /** Create a randomized time delta based on the configured time spread type.
   * Currently defined options are:
   * 0: Gaussian -> parameters[0] = mean, parameters[1] = sigma
   * 1: Uniform -> parameters[0] = min, parameters[1] = max
   * 2: Constant -> parameters[0] = value
   */

The producer validates that the option is one of the valid ones and that the parameter length is correct.

Here's the test configuration that I used to try the setup

#!/usr/bin/env python3
from LDMX.Framework import ldmxcfg
p = ldmxcfg.Process('timeshift')

p.maxTriesPerEvent = 1000

from LDMX.Biasing import ecal, util
from LDMX.SimCore import generators as gen
mySim = ecal.photo_nuclear('ldmx-det-v14',gen.single_4gev_e_upstream_tagger())
mySim.beamSpotSmear = [20.,80.,0.]
mySim.description = 'ECal PN Test Simulation'

p.sequence = [ mySim ]

##################################################################
# Below should be the same for all sim scenarios

import os
import sys

if 'LDMX_NUM_EVENTS' in os.environ:
    p.maxEvents = int(os.environ['LDMX_NUM_EVENTS'])
else:
    p.maxEvents = int(sys.argv[1])
if 'LDMX_RUN_NUMBER' in os.environ:
    p.run = int(os.environ['LDMX_RUN_NUMBER'])
else:
    p.run = 1


p.histogramFile = 'histograms.root'
p.outputFiles = ['results.root']

import LDMX.Ecal.EcalGeometry
import LDMX.Hcal.HcalGeometry
import LDMX.Hcal.hcal_hardcoded_conditions
import LDMX.Hcal.digi as hcal_digi


from LDMX.DQM import dqm
digi = hcal_digi.HcalDigiProducer()
# Uniform + Gaussian  example
digi.do_time_spread_per_spill = True
digi.time_spread_per_spill_type = 1 # Uniform
digi.time_spread_per_spill_parameters = [0.0, 1.0] # Min, Max

digi.do_time_spread_per_hit = True
digi.time_spread_per_hit_type = 0 # Gaussian
digi.time_spread_per_hit_parameters = [0.0, 10] # Mean, sigma


# Uniform only example
digi.do_time_spread_per_spill = True
digi.time_spread_per_spill_type = 1 # Uniform
digi.time_spread_per_spill_parameters = [0.0, 1.0] # Min, Max

digi.do_time_spread_per_hit = False
# digi.time_spread_per_hit_type = 0 # Gaussian
# digi.time_spread_per_hit_parameters = [0.0, 10] # Mean, sigma
#

# Fails with the following error:
# Configuration Error [InvalidParameter] : Invalid time spread type, must be 0 (Gaussian), 1 (Uniform), or 2 (Constant))
# digi.do_time_spread_per_spill = True
# digi.time_spread_per_spill_type = 4 # Gaussian

# Fails with the following error:
# Configuration Error [InvalidParameter] : Time spread type Gaussian requires 2 parameters (mean, sigma)
# digi.do_time_spread_per_hit = True
# digi.time_spread_per_hit_type = 0 # Gaussian
# digi.time_spread_per_hit_parameters = [0.0, 10, 11.0] # Too many parameters
p.sequence.extend([
        # ecal_digi.EcalDigiProducer(),
        # ecal_digi.EcalRecProducer(),
        # ecal_vetos.EcalVetoProcessor(),
    digi,
    hcal_digi.HcalRecProducer(),
        # *ts_digis,
        # TrigScintClusterProducer.pad1(),
        # TrigScintClusterProducer.pad2(),
        # TrigScintClusterProducer.pad3(),
        # trigScintTrack,
        # count, TriggerProcessor('trigger'),
        # dqm.PhotoNuclearDQM(verbose=True),
        dqm.HCalDQM(),
    # dqm.SimObjects(),
        ]
                  # + dqm.all_dqm
                  )

Copy link
Member

@tomeichlersmith tomeichlersmith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks good, I just have some (optional) ideas on how to improve the configuration.

  • Put the configuration of the time spread into functions on the python side so that the user doesn't need to remember the integers. e.g.
def uniform_spill_time_spread(self, min, max):
    self.do_time_spread_per_spill = True
    self.time_spread_per_spill_type = 1 # Uniform
    self.time_spread_per_spill_parameters = [0.0, 1.0] # Min, Max
  • Promote time spread to its own config class in python. This would avoid having a generic "parameters" variable and instead allow each of the types of spreads to have their own named variables. They would just need to share the type member variable (or similar) to allow the C++ side to deduce which type it is.
class TimeSpread:
    def __init__(self, kind):
        self.kind = kind

# instead of True/False boolean, just have separate spread class that is no spread?
class NoSpread:
    def __init__(self):
         super().__init__(-1)

# would do similar for constant and gaussian
class Uniform(TimeSpread):
    def __init__(self, min, max):
        super().__init__(1)
        self.min = min
        self.max = max

# setting the spread would become more readable and shorter
digi.time_spread_for_spill = Uniform(0.0, 1.0) 

Then on the C++ side

const auto& time_spread_for_spill = ps.getParameter<framework::config::Parameters>("time_spread_for_spill");
if (time_spread_for_spill.getParameter<int>("kind") == 1) {
  min = time_spread_for_spill.getParamter<double>("min");
}
// continue with parameter extraction...

One could even copy this class hierarchy into C++ if desired.

@EinarElen
Copy link
Contributor Author

This sounds reasonable, I'll go ahead and test it tonight!

@EinarElen EinarElen force-pushed the 69-add-the-ability-to-time-shift-simhits-before-digitizing-them branch from fd64a90 to b3655f5 Compare April 1, 2024 21:26
@tomeichlersmith
Copy link
Member

With the impending submodule->subdirectory transition on Wednesday, I am commenting here to remind you to either merge this PR before then or close it and re-apply the changes after Wednesday to make a new PR on the subdirectory of ldmx-sw.

@tomeichlersmith
Copy link
Member

I have already done the transition and am in the final stages of testing. Updating submodule changes to apply to subdirectories is not a difficult process and one that I've tested on my own branch of the ECal submodule. Please follow those instructions and re-open this PR in ldmx-sw off the new trunk.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add the ability to time-shift simhits before digitizing them
2 participants