1 #include "trg/cdc/modules/neurotrigger/CDCTriggerNeuroModule.h"
15 "The NeuroTrigger module of the CDC trigger.\n"
16 "Takes track segments and 2D track estimates as input and estimates\n"
17 "the z-vertex for each track using a neural network.\n"
18 "Requires one or several trained networks stored in a file.\n"
20 setPropertyFlags(c_ParallelProcessingCertified);
22 addParam(
"filename", m_filename,
23 "Name of the files where the NeuroTrigger parameters are saved. "
24 "When left blank, the parameters are loaded from the Conditions "
26 "(compare NeuroTriggerTrainer).",
28 addParam(
"arrayname", m_arrayname,
29 "Name of the TObjArray holding the NeuroTrigger parameters "
30 "(compare NeuroTriggerTrainer).",
32 addParam(
"hitCollectionName", m_hitCollectionName,
33 "Name of the input StoreArray of CDCTriggerSegmentHits.",
35 addParam(
"EventTimeName", m_EventTimeName,
36 "Name of the event time object.",
38 addParam(
"inputCollectionName", m_inputCollectionName,
39 "Name of the StoreArray holding the 2D input tracks or Neurotracks.",
40 string(
"TRGCDC2DFinderTracks"));
41 addParam(
"realinputCollectionName", m_realinputCollectionName,
42 "Name of the StoreArray holding the 2D input tracks in case "
43 "Neurotracks were used for the inputCollectionName.",
44 string(
"CDCTriggerNNInput2DFinderTracks"));
45 addParam(
"outputCollectionName", m_outputCollectionName,
46 "Name of the StoreArray holding the output tracks with neural "
48 string(
"TRGCDCNeuroTracks"));
49 addParam(
"fixedPoint", m_fixedPoint,
50 "Switch to turn on fixed point arithmetic for FPGA simulation.",
52 addParam(
"precision", m_precision,
53 "fixed point precision in bit after radix point (for track phi, "
54 "scaling factor, reference id, MLP nodes, MLP weights, "
55 "MLP activation function)", {12, 8, 8, 12, 10, 10});
56 addParam(
"et_option", m_et_option,
57 "option on how to obtain the event time. When left blank, the value "
58 "is loaded from the Conditions Database. Possibilities are: "
59 "'etf_only', 'fastestpriority', 'zero', 'etf_or_fastestpriority', "
60 "'etf_or_zero', 'etf_or_fastest2d', 'fastest2d'.",
62 addParam(
"writeMLPinput", m_writeMLPinput,
63 "if true, the MLP input vector will be written to the datastore "
66 addParam(
"hardwareCompatibilityMode", m_hardwareCompatibilityMode,
67 "Switch to mimic an apparent bug in the hardware preprocessing",
69 addParam(
"NeuroHWTrackInputMode", m_neuroTrackInputMode,
70 "use Neurotracks instead of 2DTracks as input",
80 if (m_et_option.size() < 1) {
81 m_et_option = m_cdctriggerneuroconfig->getUseETF() ?
"etf_or_fastestpriority" :
"fastestpriority";
82 B2DEBUG(2,
"The firmware version of the Neurotrigger boards is: " + m_cdctriggerneuroconfig->getNNTFirmwareVersionID());
84 if (!m_NeuroTrigger.load(m_filename, m_arrayname))
85 B2ERROR(
"NeuroTrigger could not be loaded correctly.");
87 m_NeuroTrigger.setPrecision(m_precision);
89 if (m_et_option ==
"") {
90 m_et_option = m_NeuroTrigger.get_et_option();
92 m_tracksNN.registerInDataStore(m_outputCollectionName);
93 m_tracks2D.isRequired(m_inputCollectionName);
94 m_segmentHits.isRequired(m_hitCollectionName);
95 m_NeuroTrigger.initializeCollections(m_hitCollectionName, m_EventTimeName, m_et_option);
97 m_tracks2D.registerRelationTo(m_tracksNN);
98 m_tracks2D.requireRelationTo(m_segmentHits);
99 m_tracksNN.registerRelationTo(m_segmentHits);
100 if (m_neuroTrackInputMode) {
101 m_realtracks2D.isRequired(m_realinputCollectionName);
102 m_realtracks2D.registerRelationTo(m_tracksNN);
104 if (m_writeMLPinput) {
105 m_mlpInput.registerInDataStore(m_outputCollectionName +
"Input");
113 case 8:
return tsid + 0.12;
114 case 4:
return tsid / 2;
115 case 3:
return tsid - 0.12;
116 case 1:
return (tsid + 0.12) / 2;
117 case 0:
return tsid / 4;
118 default:
return tsid;
125 for (
int itrack = 0; itrack < m_tracks2D.getEntries(); ++itrack) {
128 m_NeuroTrigger.updateTrackFix(*m_tracks2D[itrack]);
130 m_NeuroTrigger.updateTrack(*m_tracks2D[itrack]);
133 vector<int> geoSectors =
134 m_NeuroTrigger.selectMLPs(m_tracks2D[itrack]->getPhi0(),
135 m_tracks2D[itrack]->getKappa(1.5),
136 atan2(1., m_tracks2D[itrack]->getCotTheta()));
137 if (geoSectors.size() == 0)
continue;
139 m_NeuroTrigger.getEventTime(geoSectors[0], *m_tracks2D[itrack], m_et_option, m_neuroTrackInputMode);
141 unsigned long hitPattern =
142 m_NeuroTrigger.getInputPattern(geoSectors[0], *m_tracks2D[itrack], m_neuroTrackInputMode);
144 int isector = m_NeuroTrigger.selectMLPbyPattern(geoSectors, hitPattern, m_neuroTrackInputMode);
145 if (isector < 0)
continue;
147 vector<unsigned> hitIds;
148 if (m_neuroTrackInputMode) {
149 hitIds = m_NeuroTrigger.selectHitsHWSim(isector, *m_tracks2D[itrack]);
151 hitIds = m_NeuroTrigger.selectHits(isector, *m_tracks2D[itrack]);
153 vector<float> MLPinput = m_NeuroTrigger.getInputVector(isector, hitIds);
154 if (m_hardwareCompatibilityMode) {
155 for (
unsigned isl = 0; isl < 9; isl++) {
156 MLPinput[3 * isl] = hwInputIdShuffle(MLPinput[3 * isl], isl);
160 vector<float> target;
162 target = m_NeuroTrigger.runMLPFix(isector, MLPinput);
164 target = m_NeuroTrigger.runMLP(isector, MLPinput);
167 int zIndex = m_NeuroTrigger[isector].zIndex();
168 double z = (zIndex >= 0) ? target[zIndex] : 0.;
169 int thetaIndex = m_NeuroTrigger[isector].thetaIndex();
170 double cot = (thetaIndex >= 0) ? cos(target[thetaIndex]) / sin(target[thetaIndex]) : 0.;
172 m_tracksNN.appendNew(m_tracks2D[itrack]->getPhi0(),
173 m_tracks2D[itrack]->getOmega(),
174 m_tracks2D[itrack]->getChi2D(),
176 m_tracks2D[itrack]->getFoundOldTrack(),
177 m_tracks2D[itrack]->getDriftThreshold(),
178 m_tracks2D[itrack]->getValidStereoBit(),
179 m_tracks2D[itrack]->getExpert(),
180 m_tracks2D[itrack]->getTSVector(),
181 m_tracks2D[itrack]->getTime(),
184 m_tracks2D[itrack]->addRelationTo(NNtrack);
185 if (m_neuroTrackInputMode) {
186 m_tracks2D[itrack]->getRelatedFrom<
CDCTriggerTrack>(m_realinputCollectionName)->addRelationTo(NNtrack);
189 for (
unsigned i = 0; i < hitIds.size(); ++i) {
190 NNtrack->addRelationTo(m_segmentHits[hitIds[i]]);
192 if (m_writeMLPinput) {
195 for (
unsigned ii = 0; ii < MLPinput.size(); ++ii) {
196 MLPinput[ii] = long(MLPinput[ii] * (1 << m_precision[3])) / float(1 << m_precision[3]);
199 auto* storeInput = m_mlpInput.appendNew(MLPinput,
unsigned(isector));
200 NNtrack->addRelationTo(storeInput);