Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Realistic BTOF digitization #1635

Open
wants to merge 34 commits into
base: main
Choose a base branch
from

Conversation

ssedd1123
Copy link

Briefly, what does this PR introduce?

It's an attempt to make LGAD sensor response for Barrel TOF more realistic by doing the following,

  1. Spread charge deposition from strips that are hit directly to nearby strips.
  2. Perform digitization by converting charge deposited to electric pulse.
  3. Digitize the pulse by converting it to TDC and ADC value. ADC propto pulse height and TDC propto time when voltage crosses certain threshold.
  4. Convert the TDC and ADC value back to time and Edep by linear fit.
  5. Return the BTOF hit point as "TOFBarrelRecHit". Position is estimated by either weighted sum of ADC or just center of the cell with max ADC. It's weighted average by default, but the behavior can be changed by parameters.

Noise, edge correction and time talk correction will be developed in the future.

What kind of change does this PR introduce?

  • Bug fix (issue #__)
  • New feature (issue #__)
  • Documentation update
  • [x ] Other: Implementation of digitization and clusterization for LGADs in Barrel TOF

Please check if this PR fulfills the following:

  • Tests for the changes have been added
  • Documentation has been added / updated
  • [x ] Changes have been communicated to collaborators

Does this PR introduce breaking changes? What changes might users need to make to their code?

Does this PR change default behavior?

It replaces the content of "TOFBarrelRecHit" with results of this new clusterization. It was originally just geant point + random smearing. I have communicated to the reconstruction group and they advise that I submit this pull request so they can study the effect of having this new digitization/clusterization algorithm. They will decide if I should save the data in a new branch or replace the origin content.

ssedd1123 and others added 26 commits July 18, 2024 16:52
… distance relative to the center of the center cell. Now it's changed so spread is calculated relative to the true hit location.
…ighbors when cell ID from BitFieldDecoder for cellID is negative.
@github-actions github-actions bot added topic: tracking Relates to tracking reconstruction topic: PID Relates to PID reconstruction topic: barrel topic: digitization labels Oct 15, 2024
@veprbl veprbl changed the title Pr/btof digitization clusterization Realistic BTOF digitization/clustering Oct 15, 2024
@ruse-traveler ruse-traveler self-requested a review October 17, 2024 14:53
@veprbl
Copy link
Member

veprbl commented Oct 21, 2024

It would appear that BTOFHitReconstruction is too slow:

10000 calls, 0.32 s (  0.0%) edm4eic::ReconstructedParticle:ReconstructedChargedParticles -> edm4eic::ReconstructedParticle:ReconstructedChargedWithPFRICHTOFDIRCPIDParticles
10000 calls, 0.32 s (  0.0%) edm4eic::Vertex:CentralTrackVertices -> edm4eic::ReconstructedParticle:ReconstructedChargedParticles
20000 calls, 0.32 s (  0.0%) JEventProcessorPODIO -> edm4eic::Vertex:CentralTrackVertices
10000 calls, 4.24 s (  0.3%) ActsExamples::Trajectories:CentralCKFActsTrajectories -> Acts::TrackContainer<Acts::ConstVectorTrackContainer, Acts::ConstVectorMultiTrajectory, std::shared_ptr>:CentralCKFActsTracksUnfiltered
10000 calls, 4.53 s (  0.3%) edm4eic::TrackParameters:CentralCKFTrackParameters -> ActsExamples::Trajectories:CentralCKFActsTrajectories
10000 calls, 1586.41 s ( 95.0%) edm4eic::TrackerHit:TOFBarrelRecHit -> edm4eic::RawTrackerHit:TOFBarrelADCTDC
10000 calls, 1586.59 s ( 95.0%) edm4eic::TrackerHit:CentralTrackingRecHits -> edm4eic::TrackerHit:TOFBarrelRecHit
10000 calls, 1588.60 s ( 95.2%) edm4eic::Measurement2D:CentralTrackerMeasurements -> edm4eic::TrackerHit:CentralTrackingRecHits
10000 calls, 1657.77 s ( 99.3%) edm4eic::TrackParameters:CentralCKFTrackParameters -> edm4eic::Measurement2D:CentralTrackerMeasurements
20000 calls, 1669.07 s (100.0%) JEventProcessorPODIO -> edm4eic::TrackParameters:CentralCKFTrackParameters

@ssedd1123
Copy link
Author

I see. Interesting. I will profile my code and get back to you when I have a faster implementation.

@simonge
Copy link
Contributor

simonge commented Oct 22, 2024

Quite a lot to look over here, it might be reasonable to divide the PR up into a separate digitization and reconstruction PR. There might be scope to divide the algorithms up further too.

A couple of comments on the location of the code:
The changes made to reco.cc should be moved to BTOF.cc
The algorithm code added to detectors/BTOF should probably be in algorithms/digi where you have placed the BTOFHitDigiConfig.h

@ssedd1123
Copy link
Author

I can divide the PR, but while digi part is being reviewed and before reco part is uploaded, we have to test digi on its own.

"There might be scope to divide the algorithms up further too."

One way that come up to my mind is to separate the creation of electric pulses and the "digitizer" (sorry forgot the accurate word) which convert the pulse to digitized ADC/TDC values. It opens up to the possibility of adding noise in the pulse in the future as an intermediate class between pulse generator and digitizer. That means I have to make a electric pulse container. Please let me know if that's align with your ideas.

"The changes made to reco.cc should be moved to BTOF.cc
The algorithm code added to detectors/BTOF should probably be in algorithms/digi where you have placed the BTOFHitDigiConfig.h"

I can do that. Thanks for the suggestions.

I also find out why my code is slow. There are two major reasons. The first is that it simulates 10000 time bins for some reasons when there are only 1024 TDC values. The second is that it tries to simulate pulses in all 2*64 cells (a.k.a. pixel/strips) in a sensor, but charge sharing is usually limited to only the neighboring 2 to 3 cells at most. I can ask my code to not simulate pulses if the charge deposition is below a certain limit. I am able to speed it up by 50 times when these two issues are solved. I am finishing my code, but if you want me to break the pull request into two, I will do that. Please let me know of your opinion.

@ruse-traveler
Copy link
Contributor

Hi Tommy,

Apologies for being slow with a more thorough review, but I second Simon's suggestion of splitting it up into a couple of different PRs. That will help us enormously! I have a few general points for consideration:

  • Then, alongside moving the BTOFHitDigi.{cc,h} to src/algorithms/digitization as Simon suggested, I would also suggest thinking about the role BarrelTOFNeighborFinder plays. From what I understand, this is essentially part of the digitization algorithm, correct? If so, I would suggest merging that algorithm into the BTOFHitDigi algorithm.
  • I'd also like to make a point about the naming: these algorithms will also work for the ETOF or any TOF detector with a similar design, right? I would suggest renaming things from BTOF* to TOF* and dropping Barrel where appropriate. Part of what we want to do with the algorithms is to design them as generic as possible!
  • And lastly, I like the idea of splitting up the pulse generation and digitization! We're actually exploring a very similar strategy for the HGCROCs in the LFHCAL group. I would suggest considering the edm4hep::RawTimeSeries type as a candidate for the pulses. If it suits your needs, then we won't have to introduce a new type to the data model!

@simonge
Copy link
Contributor

simonge commented Oct 22, 2024

One way that come up to my mind is to separate the creation of electric pulses and the "digitizer" (sorry forgot the accurate word) which convert the pulse to digitized ADC/TDC values. It opens up to the possibility of adding noise in the pulse in the future as an intermediate class between pulse generator and digitizer. That means I have to make a electric pulse container. Please let me know if that's align with your ideas.

This is certainly something that will be useful in the longer term yes, although I think it's probably not essential at this point. I was thinking more about breaking it up after you've calculated the charge for each neighbour (https://github.com/eic/EICrecon/pull/1635/files#diff-acbf526d2d8f845cc80b1d9971d6165206659cd1ae2b059920290d6b6efbc972R131), from this you can save a charge shared time, charge and cellID before doing the digitization. This should allow potential contributions in the same cell from different hits to be combined and attempt to be separated by summing the landau contributions. I don't believe this is happening at the moment. I might change my mind as I look through the code.

I also find out why my code is slow. There are two major reasons. The first is that it simulates 10000 time bins for some reasons when there are only 1024 TDC values. The second is that it tries to simulate pulses in all 2*64 cells (a.k.a. pixel/strips) in a sensor, but charge sharing is usually limited to only the neighboring 2 to 3 cells at most. I can ask my code to not simulate pulses if the charge deposition is below a certain limit. I am able to speed it up by 50 times when these two issues are solved. I am finishing my code, but if you want me to break the pull request into two, I will do that. Please let me know of your opinion.

Great, that's a good start, hopefully we can speed it up a bit further. I'll try and make a few comments in the code itself.

@ssedd1123
Copy link
Author

This is certainly something that will be useful in the longer term yes, although I think it's probably not essential at this point. I was thinking more about breaking it up after you've calculated the charge for each neighbour (https://github.com/eic/EICrecon/pull/1635/files#diff-acbf526d2d8f845cc80b1d9971d6165206659cd1ae2b059920290d6b6efbc972R131), from this you can save a charge shared time, charge and cellID before doing the digitization. This should allow potential contributions in the same cell from different hits to be combined and attempt to be separated by summing the landau contributions. I don't believe this is happening at the moment. I might change my mind as I look through the code.

That can be done too. We can have three classes, the charge sharing class, the pulse generation class, and the digitization class. I am working on it.

Copy link
Contributor

@simonge simonge left a comment

Choose a reason for hiding this comment

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

A few comments to start with. Hopefully some of them useful.

src/detectors/BTOF/BTOFHitDigi.cc Outdated Show resolved Hide resolved
Comment on lines 48 to 54
bool _useCache = true;
const dd4hep::DDSegmentation::BitFieldCoder* _decoder = nullptr;
const dd4hep::Detector* _detector = nullptr;

std::unique_ptr<dd4hep::rec::CellIDPositionConverter> _converter;
std::shared_ptr<spdlog::logger> _log;
std::unordered_map<dd4hep::rec::CellID, std::shared_ptr<std::vector<dd4hep::rec::CellID>>> _cache;
Copy link
Contributor

Choose a reason for hiding this comment

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

In the rest of the code we use m_ rather than just _ to indicate a member

Copy link
Author

Choose a reason for hiding this comment

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

All object members are now renamed to use "m_" prefix. For protected functions, do you also want me to use "m_"?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'll leave this for someone more qualified to answer, I don't think we have a standard for distinguishing protected functions at the moment.

src/detectors/BTOF/BarrelTOFNeighborFinder.cc Outdated Show resolved Hide resolved

namespace eicrecon {

class BTOFHitDigi : public WithPodConfig<BTOFHitDigiConfig> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please can you convert this to use the algorithms interface we're now using for our other algorithms. e.g. https://github.com/eic/EICrecon/blob/main/src/algorithms/digi/SiliconTrackerDigi.h

This will require matching changes to BTOFHitDigi.cc process function and BTOFHitDigi_factory.h to match.

Copy link
Author

Choose a reason for hiding this comment

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

Must process be const? Is that required for multi-threading? It's mostly a concern when I want to use TF1::SetParameter in process for pulse generation. I can get around by declaring new TF1 on stack in process, but I don't know if that's a efficient way to do it.

src/detectors/BTOF/BarrelTOFNeighborFinder.cc Outdated Show resolved Hide resolved
src/detectors/BTOF/BarrelTOFNeighborFinder.cc Outdated Show resolved Hide resolved
return position;
}

dd4hep::Position BarrelTOFNeighborFinder::global2Local(const dd4hep::Position& pos) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is always a frustrating function to do from the dd4hep geometry but I think it can be simplified a bit, will have to check.

Copy link
Author

Choose a reason for hiding this comment

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

Turns out "global2Local" is not required for digitization, but I do need "cell2LocalPosition" so I can integrate the charge deposition inside a cell in sensor frame. Please see detector/BTOFChargeSharing

@ssedd1123
Copy link
Author

  • And lastly, I like the idea of splitting up the pulse generation and digitization! We're actually exploring a very similar strategy for the HGCROCs in the LFHCAL group. I would suggest considering the edm4hep::RawTimeSeries type as a candidate for the pulses. If it suits your needs, then we won't have to introduce a new type to the data model!

I tried to use edm4hep::RawTimeSeries, but I can't find documents on this container. I don't know what is the interface for appending voltage at different time bins. I can't find any example code on EICrecon or EDM4hep. How do I append to adcCounts (which I assumed is the member of type vector?) Thanks for your help.

@ruse-traveler
Copy link
Contributor

  • And lastly, I like the idea of splitting up the pulse generation and digitization! We're actually exploring a very similar strategy for the HGCROCs in the LFHCAL group. I would suggest considering the edm4hep::RawTimeSeries type as a candidate for the pulses. If it suits your needs, then we won't have to introduce a new type to the data model!

I tried to use edm4hep::RawTimeSeries, but I can't find documents on this container. I don't know what is the interface for appending voltage at different time bins. I can't find any example code on EICrecon or EDM4hep. How do I append to adcCounts (which I assumed is the member of type vector?) Thanks for your help.

Ah! So the interface is the same as when adding to any other vector member of an edm4hep or edm4eic type, so e.g.

edm4hep::MutableRawTimeSeries series;
for (int32_t sample : my_samples) {
  series.addToAdcCounts( sample );
}

You can see it "in situ" on our HGCROC development branch (we're not very far along). And you can see some parallel examples of adding to the hits and weights vector of an edm4eic::ProtoCluster here.

ssedd1123 and others added 2 commits October 23, 2024 10:51
…hree parts: 1. Charge sharing, 2. Pulse generation, 3. Pulse digitization.
@ssedd1123 ssedd1123 changed the title Realistic BTOF digitization/clustering Realistic BTOF digitization Oct 23, 2024
@ssedd1123
Copy link
Author

I have broken down my BTOFHigDigi into three classes: BTOFChargeSharing, TOFPulseGeneration and TOFPulseDigitization. I removed BTOFHitReconstruction and save it for a later pull request as advised.

Hi Tommy,

Apologies for being slow with a more thorough review, but I second Simon's suggestion of splitting it up into a couple of different PRs. That will help us enormously! I have a few general points for consideration:

  • Then, alongside moving the BTOFHitDigi.{cc,h} to src/algorithms/digitization as Simon suggested, I would also suggest thinking about the role BarrelTOFNeighborFinder plays. From what I understand, this is essentially part of the digitization algorithm, correct? If so, I would suggest merging that algorithm into the BTOFHitDigi algorithm.

It's done. All functionalities of BarrelTOFNeighborFinder has been integrated into BTOFChargeSharing.

  • I'd also like to make a point about the naming: these algorithms will also work for the ETOF or any TOF detector with a similar design, right? I would suggest renaming things from BTOF* to TOF* and dropping Barrel where appropriate. Part of what we want to do with the algorithms is to design them as generic as possible!

I removed the "B" from TOFPulseGeneration and TOFPulseDigitization because, like you've said, the same algorithm should work on ETOF even though I haven't tried it. I keep the "B" in BTOFChargeSharing because the meaning of cellID differs slightly between BTOF and ETOF so I am sure the charge sharing part can't work with anything other than BTOF.

  • And lastly, I like the idea of splitting up the pulse generation and digitization! We're actually exploring a very similar strategy for the HGCROCs in the LFHCAL group. I would suggest considering the edm4hep::RawTimeSeries type as a candidate for the pulses. If it suits your needs, then we won't have to introduce a new type to the data model!

Thanks for your recommendation. I took your advise and implemented it in TOFPulseGeneration and TOFPulseDigitization . Please take a look

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: barrel topic: digitization topic: PID Relates to PID reconstruction topic: tracking Relates to tracking reconstruction
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants