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 <TTree.h>
21#include <TFile.h>
22#include <TBranch.h>
23
24#include <iostream>
25#include <cmath>
26
27using namespace Belle2;
28using namespace CDC;
29using namespace TrackFindingCDC;
30using namespace TrackingUtilities;
31
33
34float getDist2D(const CDCTrajectory3D& trajectory, const CDCWireHit* wireHit)
35{
36 const CDCTrajectory2D& trajectory2D = trajectory.getTrajectory2D();
37 const CDCTrajectorySZ& trajectorySZ = trajectory.getTrajectorySZ();
38 Vector2D recoPos2D;
39 if (wireHit->isAxial()) {
40 recoPos2D = wireHit->reconstruct2D(trajectory2D);
41 } else {
42 const CDCWire& wire = wireHit->getWire();
43 const Vector2D& posOnXYPlane = wireHit->reconstruct2D(trajectory2D);
44 const double arcLength = trajectory2D.calcArcLength2D(posOnXYPlane);
45 const double z = trajectorySZ.mapSToZ(arcLength);
46 const Vector2D& wirePos2DAtZ = wire.getWirePos2DAtZ(z);
47 const Vector2D& recoPosOnTrajectory = trajectory2D.getClosest(wirePos2DAtZ);
48 const double driftLength = wireHit->getRefDriftLength();
49 Vector2D disp2D = recoPosOnTrajectory - wirePos2DAtZ;
50 disp2D.normalizeTo(driftLength);
51 recoPos2D = wirePos2DAtZ + disp2D;
52 }
53 const float distanceToHit = trajectory2D.getDist2D(recoPos2D);
54 return std::abs(distanceToHit);
55}
56
58{
60 // database:
61 m_channelMapFromDB = std::make_unique<DBArray<CDCChannelMap>> ();
62
63 if ((*m_channelMapFromDB).isValid()) {
64 B2DEBUG(29, "CDC Channel map is valid");
65 } else {
66 B2FATAL("CDC Channel map is not valid");
67 }
68
69 // Library for writing
70
71 auto leavesCreator = [this](TTree & tree) {
73 tree.Branch("Dist", &m_dist_signal, "DistSig/f:DistBg/f");
74 tree.Branch("ADC", &m_adc_sig, "ADC_Sig/S:ADC_bg/S");
75 tree.Branch("Track", &m_n_hit_track, "tr_nhit/S");
76 }
77 tree.Branch("Board", &m_board, "board/b");
78 tree.Branch("Channel", &m_channel, "channel/b");
79 tree.Branch("Nhit", &m_n_hit, "nhit/b");
80 tree.Branch("Asic", &m_asic_info[0],
81 "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");
82 return;
83 };
84
85 m_recorder.reset(new Recorder(
86 leavesCreator
88 , "ASIC"));
89}
90
92{
94 // Load map from DB:
95 for (const auto& cm : (*m_channelMapFromDB)) {
96 const int isl = cm.getISuperLayer();
97 const int il = cm.getILayer();
98 const int iw = cm.getIWire();
99 const int iBoard = cm.getBoardID();
100 const int iCh = cm.getBoardChannel();
101 const WireID wireId(isl, il, iw);
102 m_map[wireId.getEWire()] = std::pair<int, int>(iBoard, iCh);
103 }
104}
105
107{
108 return "Finds suitable ASICs with a single hit attached to a track and uses them to create the library";
109}
110
111void AsicBackgroundLibraryCreator::apply(const std::vector<CDCWireHit>& wireHits, const std::vector<CDCTrack>& tracks)
112{
113
114 std::map< std::pair<int, int>, std::vector<const CDCWireHit*>> groupedByAsic;
115 for (const CDCWireHit& wireHit : wireHits) {
116 auto eWire = wireHit.getWireID().getEWire();
117 B2ASSERT("Channel map NOT found for the channel", m_map.count(eWire) > 0);
118 auto board = m_map[eWire].first;
119 auto channel = m_map[eWire].second;
120 auto asicID = std::pair<int, int>(board, channel / 8); // ASIC are groups of 8 channels
121 groupedByAsic[asicID].push_back(&wireHit);
122 };
123 for (auto& asicList : groupedByAsic) {
124 selectAsic(asicList.second, tracks);
125 };
126
127 return;
128}
129
130void AsicBackgroundLibraryCreator::exposeParameters(ModuleParamList* moduleParamList, const std::string& prefix)
131{
132 Super::exposeParameters(moduleParamList, prefix);
133 moduleParamList->addParameter(prefixed(prefix, "minimalHitNumberASIC"),
135 "Required number of hits per ASIC for library creation",
137
138 moduleParamList->addParameter(prefixed(prefix, "AsicLibraryFileName"),
140 "ASIC library file name",
142
143 moduleParamList->addParameter(prefixed(prefix, "maximalDistanceSignal"),
145 "maximal distance in cm from track to signal hit",
147
148 moduleParamList->addParameter(prefixed(prefix, "minimalDistanceBackground"),
150 "minimal distance in cm from track to background hit",
152
153 moduleParamList->addParameter(prefixed(prefix, "useAxialHitsOnly"),
155 "use axial layers only",
157
158 moduleParamList->addParameter(prefixed(prefix, "writeExtraVars"),
160 "Write extra variables to the library",
162
163 moduleParamList->addParameter(prefixed(prefix, "minimalHitsOnTrack"),
165 "Required number of hits on track for library creation",
167
168 // set some defaults:
169 moduleParamList->getParameter<std::string>("inputTracks").setDefaultValue("CDCTrackVector");
170 moduleParamList->getParameter<std::string>("inputWireHits").setDefaultValue("CDCWireHitVector");
171}
172
178
179void AsicBackgroundLibraryCreator::selectAsic(const std::vector<const CDCWireHit*>& wireHits, const std::vector<CDCTrack>& tracks)
180{
181
182 if (wireHits.size() < m_minimal_hit_number) {
183 return;
184 };
185
186 if (wireHits.size() > 8) {
187 B2ERROR("Number of hits per asic should not exceed 8, observe too many hits." << LogVar("nHits", wireHits.size()));
189 return;
190 }
191
192
193 // count taken non-background hits:
194 int count = 0;
195 const CDCWireHit* signal = nullptr;
196 for (auto& hit : wireHits) {
197 if (!(*hit)->hasBackgroundFlag() && (*hit)->hasTakenFlag()) {
198 count += 1;
199 signal = hit;
200 }
201 }
202
203 // require one and only one taken hit
204 if (count != 1) {
205 return;
206 }
207
208
209 // check if only axial hits are used:
210
211 if ((!signal->isAxial()) && m_use_axial_hits_only) {
212 return;
213 }
214
215 // find the track to which this hit belongs
216 const CDCTrack* signalTrack = nullptr;
217 for (auto& track : tracks) {
218 for (auto& hit : track) {
219 if (&hit.getWireHit() == signal) {
220 signalTrack = &track;
221 break;
222 }
223 }
224 if (signalTrack != nullptr) {
225 break;
226 }
227 }
228
229 if (signalTrack == nullptr) {
230 B2DEBUG(29, "AsicBackgroundLibraryCreator::No track found for the signal hit");
231 return;
232 }
233
234 m_n_hit_track = signalTrack->size();
235
237
238 // check the distance from the track to each signal hit
239 const auto& trajectory = signalTrack->getStartTrajectory3D();
240
241 m_dist_bg = 1000.;
242
243 for (auto& hit : wireHits) {
244
245 const float dist = getDist2D(trajectory, hit);
246
247
248 if (hit == signal) {
249 m_dist_signal = dist;
250 if (dist > m_distance_signal_max) return;
251 } else {
252 m_dist_bg = std::min(m_dist_bg, dist);
253 if (dist < m_distance_background_min) return;
254 }
255 }
256
257
258 // Ok, passes all cuts !
259
260 // reset the library entries
261 for (auto& channel : m_asic_info) {
262 channel.TDC = -1;
263 channel.ADC = -1;
264 channel.TOT = -1;
265 }
266
267 // add to the library
268
269 m_n_hit = wireHits.size();
270
271 m_adc_max_bg = 0;
272 for (auto& hit : wireHits) {
273 auto eWire = hit->getWireID().getEWire();
274 auto channel = m_map[eWire].second;
275 auto asicCH = channel % 8;
276 m_asic_info[asicCH].ADC = hit->getHit()->getADCCount();
277 m_asic_info[asicCH].TDC = hit->getHit()->getTDCCount();
278 m_asic_info[asicCH].TOT = hit->getHit()->getTOT();
279
280 if (hit != signal) {
281 m_adc_max_bg = std::max(m_adc_max_bg, m_asic_info[asicCH].ADC);
282 }
283 }
284 // also signal hit info
285 auto eWire = signal->getWireID().getEWire();
286 m_channel = m_map[eWire].second;
287 m_board = m_map[eWire].first;
288 m_adc_sig = signal->getHit()->getADCCount();
289
290 // make sure that ADC of the signal is >= than ADC of the background:
291 if (m_adc_sig < m_adc_max_bg) return;
292
293 // write out
294 m_recorder->capture();
295}
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:39
Particle trajectory as it is seen in xy projection represented as a circle.
double calcArcLength2D(const Vector2D &point) const
Calculate the travel distance from the start position of the trajectory.
Vector2D getClosest(const Vector2D &point) const
Calculates the closest approach on the trajectory to the given point.
double getDist2D(const Vector2D &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:58
const WireID & getWireID() const
Getter for the WireID of the wire the hit is located on.
Definition CDCWireHit.h:188
Class to fill a tree from a set of variables.
Definition Recorder.h:29
A two dimensional vector which is equipped with functions for correct handling of orientation relate...
Definition Vector2D.h:36
double normalizeTo(const double toLength)
Normalizes the vector to the given length.
Definition Vector2D.h:344
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.