Belle II Software development
AsicBackgroundLibraryCreator.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <tracking/trackFindingCDC/findlets/complete/AsicBackgroundLibraryCreator.h>
10#include <tracking/trackingUtilities/eventdata/hits/CDCWireHit.h>
11#include <tracking/trackingUtilities/eventdata/tracks/CDCTrack.h>
12#include <tracking/trackingUtilities/eventdata/trajectories/CDCTrajectory2D.h>
13#include <tracking/trackingUtilities/eventdata/trajectories/CDCTrajectorySZ.h>
14#include <cdc/topology/CDCWire.h>
15#include <tracking/trackingUtilities/utilities/StringManipulation.h>
16#include <framework/core/ModuleParamList.templateDetails.h>
17#include <cdc/dataobjects/CDCHit.h>
18#include <framework/logging/Logger.h>
19
20#include <Math/Vector2D.h>
21#include <TTree.h>
22#include <TFile.h>
23#include <TBranch.h>
24
25#include <iostream>
26#include <cmath>
27
28using namespace Belle2;
29using namespace CDC;
30using namespace TrackFindingCDC;
31using namespace TrackingUtilities;
32
34
35float getDist2D(const CDCTrajectory3D& trajectory, const CDCWireHit* wireHit)
36{
37 const CDCTrajectory2D& trajectory2D = trajectory.getTrajectory2D();
38 const CDCTrajectorySZ& trajectorySZ = trajectory.getTrajectorySZ();
39 ROOT::Math::XYVector recoPos2D;
40 if (wireHit->isAxial()) {
41 recoPos2D = wireHit->reconstruct2D(trajectory2D);
42 } else {
43 const CDCWire& wire = wireHit->getWire();
44 const ROOT::Math::XYVector& posOnXYPlane = wireHit->reconstruct2D(trajectory2D);
45 const double arcLength = trajectory2D.calcArcLength2D(posOnXYPlane);
46 const double z = trajectorySZ.mapSToZ(arcLength);
47 const ROOT::Math::XYVector& wirePos2DAtZ = wire.getWirePos2DAtZ(z);
48 const ROOT::Math::XYVector& recoPosOnTrajectory = trajectory2D.getClosest(wirePos2DAtZ);
49 const double driftLength = wireHit->getRefDriftLength();
50 ROOT::Math::XYVector disp2D = recoPosOnTrajectory - wirePos2DAtZ;
51 if (disp2D.R() != 0.0) {
52 disp2D *= (driftLength / disp2D.R());
53 }
54 recoPos2D = wirePos2DAtZ + disp2D;
55 }
56 const float distanceToHit = trajectory2D.getDist2D(recoPos2D);
57 return std::abs(distanceToHit);
58}
59
61{
63 // database:
64 m_channelMapFromDB = std::make_unique<DBArray<CDCChannelMap>> ();
65
66 if ((*m_channelMapFromDB).isValid()) {
67 B2DEBUG(29, "CDC Channel map is valid");
68 } else {
69 B2FATAL("CDC Channel map is not valid");
70 }
71
72 // Library for writing
73
74 auto leavesCreator = [this](TTree & tree) {
76 tree.Branch("Dist", &m_dist_signal, "DistSig/f:DistBg/f");
77 tree.Branch("ADC", &m_adc_sig, "ADC_Sig/S:ADC_bg/S");
78 tree.Branch("Track", &m_n_hit_track, "tr_nhit/S");
79 }
80 tree.Branch("Board", &m_board, "board/b");
81 tree.Branch("Channel", &m_channel, "channel/b");
82 tree.Branch("Nhit", &m_n_hit, "nhit/b");
83 tree.Branch("Asic", &m_asic_info[0],
84 "TDC0/S:ADC0/S:TOT0/S:TDC1/S:ADC1/S:TOT1/S:TDC2/S:ADC2/S:TOT2/S:TDC3/S:ADC3/S:TOT3/S:TDC4/S:ADC4/S:TOT4/S:TDC5/S:ADC5/S:TOT5/S:TDC6/S:ADC6/S:TOT6/S:TDC7/S:ADC7/S:TOT7/S");
85 return;
86 };
87
88 m_recorder.reset(new Recorder(
89 leavesCreator
91 , "ASIC"));
92}
93
95{
97 // Load map from DB:
98 for (const auto& cm : (*m_channelMapFromDB)) {
99 const int isl = cm.getISuperLayer();
100 const int il = cm.getILayer();
101 const int iw = cm.getIWire();
102 const int iBoard = cm.getBoardID();
103 const int iCh = cm.getBoardChannel();
104 const WireID wireId(isl, il, iw);
105 m_map[wireId.getEWire()] = std::pair<int, int>(iBoard, iCh);
106 }
107}
108
110{
111 return "Finds suitable ASICs with a single hit attached to a track and uses them to create the library";
112}
113
114void AsicBackgroundLibraryCreator::apply(const std::vector<CDCWireHit>& wireHits, const std::vector<CDCTrack>& tracks)
115{
116
117 std::map< std::pair<int, int>, std::vector<const CDCWireHit*>> groupedByAsic;
118 for (const CDCWireHit& wireHit : wireHits) {
119 auto eWire = wireHit.getWireID().getEWire();
120 B2ASSERT("Channel map NOT found for the channel", m_map.count(eWire) > 0);
121 auto board = m_map[eWire].first;
122 auto channel = m_map[eWire].second;
123 auto asicID = std::pair<int, int>(board, channel / 8); // ASIC are groups of 8 channels
124 groupedByAsic[asicID].push_back(&wireHit);
125 };
126 for (auto& asicList : groupedByAsic) {
127 selectAsic(asicList.second, tracks);
128 };
129
130 return;
131}
132
133void AsicBackgroundLibraryCreator::exposeParameters(ModuleParamList* moduleParamList, const std::string& prefix)
134{
135 Super::exposeParameters(moduleParamList, prefix);
136 moduleParamList->addParameter(prefixed(prefix, "minimalHitNumberASIC"),
138 "Required number of hits per ASIC for library creation",
140
141 moduleParamList->addParameter(prefixed(prefix, "AsicLibraryFileName"),
143 "ASIC library file name",
145
146 moduleParamList->addParameter(prefixed(prefix, "maximalDistanceSignal"),
148 "maximal distance in cm from track to signal hit",
150
151 moduleParamList->addParameter(prefixed(prefix, "minimalDistanceBackground"),
153 "minimal distance in cm from track to background hit",
155
156 moduleParamList->addParameter(prefixed(prefix, "useAxialHitsOnly"),
158 "use axial layers only",
160
161 moduleParamList->addParameter(prefixed(prefix, "writeExtraVars"),
163 "Write extra variables to the library",
165
166 moduleParamList->addParameter(prefixed(prefix, "minimalHitsOnTrack"),
168 "Required number of hits on track for library creation",
170
171 // set some defaults:
172 moduleParamList->getParameter<std::string>("inputTracks").setDefaultValue("CDCTrackVector");
173 moduleParamList->getParameter<std::string>("inputWireHits").setDefaultValue("CDCWireHitVector");
174}
175
181
182void AsicBackgroundLibraryCreator::selectAsic(const std::vector<const CDCWireHit*>& wireHits, const std::vector<CDCTrack>& tracks)
183{
184
185 if (wireHits.size() < m_minimal_hit_number) {
186 return;
187 };
188
189 if (wireHits.size() > 8) {
190 B2ERROR("Number of hits per asic should not exceed 8, observe too many hits." << LogVar("nHits", wireHits.size()));
192 return;
193 }
194
195
196 // count taken non-background hits:
197 int count = 0;
198 const CDCWireHit* signal = nullptr;
199 for (auto& hit : wireHits) {
200 if (!(*hit)->hasBackgroundFlag() && (*hit)->hasTakenFlag()) {
201 count += 1;
202 signal = hit;
203 }
204 }
205
206 // require one and only one taken hit
207 if (count != 1) {
208 return;
209 }
210
211
212 // check if only axial hits are used:
213
214 if ((!signal->isAxial()) && m_use_axial_hits_only) {
215 return;
216 }
217
218 // find the track to which this hit belongs
219 const CDCTrack* signalTrack = nullptr;
220 for (auto& track : tracks) {
221 for (auto& hit : track) {
222 if (&hit.getWireHit() == signal) {
223 signalTrack = &track;
224 break;
225 }
226 }
227 if (signalTrack != nullptr) {
228 break;
229 }
230 }
231
232 if (signalTrack == nullptr) {
233 B2DEBUG(29, "AsicBackgroundLibraryCreator::No track found for the signal hit");
234 return;
235 }
236
237 m_n_hit_track = signalTrack->size();
238
240
241 // check the distance from the track to each signal hit
242 const auto& trajectory = signalTrack->getStartTrajectory3D();
243
244 m_dist_bg = 1000.;
245
246 for (auto& hit : wireHits) {
247
248 const float dist = getDist2D(trajectory, hit);
249
250
251 if (hit == signal) {
252 m_dist_signal = dist;
253 if (dist > m_distance_signal_max) return;
254 } else {
255 m_dist_bg = std::min(m_dist_bg, dist);
256 if (dist < m_distance_background_min) return;
257 }
258 }
259
260
261 // Ok, passes all cuts !
262
263 // reset the library entries
264 for (auto& channel : m_asic_info) {
265 channel.TDC = -1;
266 channel.ADC = -1;
267 channel.TOT = -1;
268 }
269
270 // add to the library
271
272 m_n_hit = wireHits.size();
273
274 m_adc_max_bg = 0;
275 for (auto& hit : wireHits) {
276 auto eWire = hit->getWireID().getEWire();
277 auto channel = m_map[eWire].second;
278 auto asicCH = channel % 8;
279 m_asic_info[asicCH].ADC = hit->getHit()->getADCCount();
280 m_asic_info[asicCH].TDC = hit->getHit()->getTDCCount();
281 m_asic_info[asicCH].TOT = hit->getHit()->getTOT();
282
283 if (hit != signal) {
284 m_adc_max_bg = std::max(m_adc_max_bg, m_asic_info[asicCH].ADC);
285 }
286 }
287 // also signal hit info
288 auto eWire = signal->getWireID().getEWire();
289 m_channel = m_map[eWire].second;
290 m_board = m_map[eWire].first;
291 m_adc_sig = signal->getHit()->getADCCount();
292
293 // make sure that ADC of the signal is >= than ADC of the background:
294 if (m_adc_sig < m_adc_max_bg) return;
295
296 // write out
297 m_recorder->capture();
298}
Class representing a sense wire in the central drift chamber.
Definition CDCWire.h:50
ROOT::Math::XYVector getWirePos2DAtZ(const double z) const
Gives the xy projected position of the wire at the given z coordinate.
Definition CDCWire.h:184
The Module parameter list class.
double m_distance_signal_max
maximal distance from track to signal hit
std::unique_ptr< DBArray< CDCChannelMap > > m_channelMapFromDB
Channel map retrieved from DB.
void selectAsic(const std::vector< const TrackingUtilities::CDCWireHit * > &wireHits, const std::vector< TrackingUtilities::CDCTrack > &tracks)
Algorithm to select suitable ASIC for library creation.
void initialize() final
Access database here, open library for writing:
void apply(const std::vector< TrackingUtilities::CDCWireHit > &wireHits, const std::vector< TrackingUtilities::CDCTrack > &tracks) final
Main algorithm marking hit as background.
std::map< int, std::pair< int, int > > m_map
map from ewire to board/channel ID
std::string getDescription() final
Short description of the findlet.
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) final
Expose the parameters to a module.
UChar_t m_n_hit
For debugging, store also number of channels with hits.
double m_distance_background_min
minimal distance from track to background hit
size_t m_minimal_hit_number
min. number of hits in ASIC for background check
std::unique_ptr< TrackingUtilities::Recorder > m_recorder
Recorder for the root output.
Class representing a sequence of three dimensional reconstructed hits.
Definition CDCTrack.h:37
Particle trajectory as it is seen in xy projection represented as a circle.
ROOT::Math::XYVector getClosest(const ROOT::Math::XYVector &point) const
Calculates the closest approach on the trajectory to the given point.
double calcArcLength2D(const ROOT::Math::XYVector &point) const
Calculate the travel distance from the start position of the trajectory.
double getDist2D(const ROOT::Math::XYVector &point) const
Calculates the distance from the point to the trajectory as seen from the xy projection.
Particle full three dimensional trajectory.
CDCTrajectory2D getTrajectory2D() const
Getter for the two dimensional trajectory.
CDCTrajectorySZ getTrajectorySZ() const
Getter for the sz trajectory.
double mapSToZ(const double s=0) const
Translates the travel distance to the z coordinate.
Class representing a hit wire in the central drift chamber.
Definition CDCWireHit.h:56
const WireID & getWireID() const
Getter for the WireID of the wire the hit is located on.
Definition CDCWireHit.h:186
Class to fill a tree from a set of variables.
Definition Recorder.h:29
Class to identify a wire inside the CDC.
Definition WireID.h:34
unsigned short getEWire() const
Getter for encoded wire number.
Definition WireID.h:154
Class to store variables with their name which were sent to the logging service.
ModuleParam< T > & getParameter(const std::string &name) const
Returns a reference to a parameter.
void addParameter(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
Abstract base class for different kinds of events.