8#include "trg/cdc/modules/neurotrigger/CDCTriggerNeuroModule.h"
22 "The NeuroTrigger module of the CDC trigger.\n"
23 "Takes track segments and 2D track estimates as input and estimates\n"
24 "the z-vertex for each track using a neural network.\n"
25 "Requires one or several trained networks stored in a file.\n"
30 "Name of the files where the NeuroTrigger parameters are saved. "
31 "When left blank, the parameters are loaded from the Conditions "
33 "(compare NeuroTriggerTrainer).",
36 "Name of the TObjArray holding the NeuroTrigger parameters "
37 "(compare NeuroTriggerTrainer).",
40 "Name of the input StoreArray of CDCTriggerSegmentHits.",
43 "Name of the event time object.",
46 "Name of the StoreArray holding the 2D input tracks or Neurotracks.",
47 string(
"TRGCDC2DFinderTracks"));
49 "Name of the StoreArray holding the 2D input tracks in case "
50 "Neurotracks were used for the inputCollectionName.",
51 string(
"CDCTriggerNNInput2DFinderTracks"));
53 "Name of the StoreArray holding the output tracks with neural "
55 string(
"TRGCDCNeuroTracks"));
57 "Switch to turn on fixed point arithmetic for FPGA simulation.",
60 "fixed point precision in bit after radix point (for track phi, "
61 "scaling factor, reference id, MLP nodes, MLP weights, "
62 "MLP activation function)", {12, 8, 8, 12, 10, 10});
64 "option on how to obtain the event time. When left blank, the value "
65 "is loaded from the Conditions Database. Possibilities are: "
66 "'etf_only', 'fastestpriority', 'zero', 'etf_or_fastestpriority', "
67 "'etf_or_zero', 'etf_or_fastest2d', 'fastest2d','min_etf_fastestpriority' (take the smaller one), 'etfcc' for the unpacked etf in the corresponding cc, 'etfcc_or_fastestpriority', 'etfcc_or_zero', 'etfhwin' for the recalculated time used in hw input. Last two options are only available for neurotrackinputode.",
70 "if true, the MLP input vector will be written to the datastore "
74 "Switch to mimic an apparent bug in the hardware preprocessing",
77 "use Neurotracks instead of 2DTracks as input",
80 "require at least 4 axial track segments",
92 B2DEBUG(2,
"The firmware version of the Neurotrigger boards is: " +
m_cdctriggerneuroconfig->getNNTFirmwareVersionID());
95 B2ERROR(
"NeuroTrigger could not be loaded correctly.");
123 case 8:
return tsid + 0.12;
124 case 4:
return tsid / 2;
125 case 3:
return tsid - 0.12;
126 case 1:
return (tsid + 0.12) / 2;
127 case 0:
return tsid / 4;
128 default:
return tsid;
143 vector<int> geoSectors =
146 atan2(1.,
m_tracks2D[itrack]->getCotTheta()));
147 if (geoSectors.size() == 0)
continue;
151 unsigned long hitPattern =
154 unsigned long chitPattern =
160 if ((chitPattern & 341) != 341 &&
161 (chitPattern & 341) != 340 &&
162 (chitPattern & 341) != 337 &&
163 (chitPattern & 341) != 325 &&
164 (chitPattern & 341) != 277 &&
165 (chitPattern & 341) != 85 &&
167 B2DEBUG(250,
"Not enough axial hits (<4), setting track invalid!");
171 unsigned long puredriftth =
175 if (isector < 0)
continue;
177 vector<unsigned> hitIds;
185 for (
unsigned isl = 0; isl < 9; isl++) {
190 vector<float> target;
198 double z = (zIndex >= 0) ? target[zIndex] : 0.;
200 double cot = (thetaIndex >= 0) ? cos(target[thetaIndex]) / sin(target[thetaIndex]) : 0.;
201 std::vector<unsigned> tsvector(9, 0);
202 for (
unsigned i = 0; i < hitIds.size(); ++i) {
206 std::vector<bool> driftthreshold;
207 for (
int k = 8; k >= 0; k--) {
208 driftthreshold.push_back(!tsvector[k] ||
static_cast<bool>((puredriftth & (1 << k)) >> k));
216 if (tphi > -1 * M_PI_4 && tphi < 1 * M_PI_4) { quadrant = 3; }
217 else if (tphi > 1 * M_PI_4 && tphi < 3 * M_PI_4) { quadrant = 0; }
218 else if (tphi > 3 * M_PI_4 || tphi < -3 * M_PI_4) { quadrant = 1; }
219 else if (tphi > -3 * M_PI_4 && tphi < -1 * M_PI_4) { quadrant = 2; }
239 std::stringstream intomega;
240 std::stringstream intphi;
241 std::stringstream intz;
242 std::stringstream inttheta;
243 intomega << std::fixed << std::setprecision(0) << NNtrack->getOmega() /
Const::speedOfLight / 1.5e-4 * 0.3 * 34.;
244 intphi << std::fixed << std::setprecision(0) << (((NNtrack->getPhi0() - M_PI / 2.*NNtrack->
getQuadrant()) - M_PI / 4.) * 2 *
247 std::vector<float> recalcsw(0.);
248 recalcsw =
m_cdctriggerneuroconfig->getMLPs()[0].scaleTarget({
static_cast<float>(NNtrack->getZ0()),
static_cast<float>(NNtrack->getDirection().Theta())});
249 intz << std::fixed << std::setprecision(0) << recalcsw[0] * 4096;
250 inttheta << std::fixed << std::setprecision(0) << recalcsw[1] * 4096;
252 NNtrack->setRawOmega(std::stoi(intomega.str()));
254 NNtrack->setRawZ(std::stoi(intz.str()));
255 NNtrack->setRawTheta(std::stoi(inttheta.str()));
256 NNtrack->setHasETFTime(
m_tracks2D[itrack]->getHasETFTime());
257 NNtrack->setETF_unpacked(
m_tracks2D[itrack]->getETF_unpacked());
258 NNtrack->setETF_recalced(
m_tracks2D[itrack]->getETF_recalced());
265 for (
unsigned i = 0; i < hitIds.size(); ++i) {
271 for (
unsigned ii = 0; ii < MLPinput.size(); ++ii) {
276 NNtrack->addRelationTo(storeInput);
std::string m_EventTimeName
name of the event time StoreObjPtr
StoreArray< CDCTriggerTrack > m_tracks2D
list of input 2D tracks or neurotracks
DBObjPtr< CDCTriggerNeuroConfig > m_cdctriggerneuroconfig
get NNT payload from database.
CDCTriggerNeuroModule()
Constructor, for setting module description and parameters.
StoreArray< CDCTriggerTrack > m_realtracks2D
list of input real 2D tracks
StoreArray< CDCTriggerTrack > m_tracksNN
list of output NN tracks
virtual void initialize() override
Initialize the module.
StoreArray< CDCTriggerMLPInput > m_mlpInput
list of input vectors for each NN track
virtual void event() override
Called once for each event.
StoreArray< CDCTriggerSegmentHit > m_segmentHits
list of track segment hits
std::string m_outputCollectionName
Name of the StoreArray containing the resulting NN tracks.
NeuroTrigger m_NeuroTrigger
Instance of the NeuroTrigger.
std::vector< unsigned > m_precision
Fixed point precision in bit after radix point.
std::string m_arrayname
Name of the TObjArray holding the networks.
float hwInputIdShuffle(float tsid, int sl)
shuffle the input ids in the input vector to match the hardware
bool m_neuroTrackInputMode
use Neurotracks as InputTracks
std::string m_inputCollectionName
Name of the StoreArray containing the input 2D tracks or neurotracks.
bool m_fixedPoint
Switch to execute the network with fixed point calculation.
bool m_writeMLPinput
Switch for writing out the input vector for each track (off by default).
std::string m_et_option
way to obtain the event time, possible values are: "etf_only" : only ETF info is used,...
std::string m_realinputCollectionName
Name of the StoreArray containing the real input 2D tracks.
std::string m_filename
Name of file where network weights etc.
bool m_min4axials
require at least 4 axial track segments
std::string m_hitCollectionName
Name of the StoreArray containing the input track segment hits.
bool m_hardwareCompatibilityMode
Switch to mimic an apparent bug in the hardware preprocessing.
Track created by the CDC trigger.
void setRawPhi0(const int phi0)
setter and getter functions for raw track values
short getQuadrant() const
get the quadrant
static const double speedOfLight
[cm/ns]
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
unsigned long getPureDriftThreshold(unsigned isector, const CDCTriggerTrack &track, const bool neurotrackinputmode)
Get the drift threshold bits, where the time of the TS was outside of the accepted time window and th...
std::vector< int > selectMLPs(float phi0, float invpt, float theta)
Select all matching expert MLPs based on the given track parameters.
void updateTrack(const CDCTriggerTrack &track)
Calculate 2D phi position and arclength for the given track and store them.
bool load(const std::string &filename, const std::string &arrayname="MLPs")
Load MLPs from file.
std::vector< unsigned > selectHits(unsigned isector, const CDCTriggerTrack &track, bool returnAllRelevant=false)
Select best hits for each super layer.
std::vector< float > runMLPFix(unsigned isector, std::vector< float > input)
Run an expert MLP with fixed point arithmetic.
void initializeCollections(std::string hitCollectionName, std::string eventTimeName, const std::string &et_option)
set the hit collection and event time to required and store the hit collection name
std::vector< float > getInputVector(unsigned isector, const std::vector< unsigned > &hitIds)
Calculate input values for MLP.
int selectMLPbyPattern(std::vector< int > &MLPs, unsigned long pattern, const bool neurotrackinputmode)
Select one MLP from a list of sector indices.
std::string get_et_option()
Return value of m_et_option.
unsigned long getInputPattern(unsigned isector, const CDCTriggerTrack &track, const bool neurotrackinputmode)
Calculate input pattern for MLP.
void updateTrackFix(const CDCTriggerTrack &track)
Calculate 2D phi position and arclength for the given track and store them.
std::vector< unsigned > selectHitsHWSim(unsigned isector, const CDCTriggerTrack &track)
Select hits for each super layer from the ones related to input track.
void setPrecision(const std::vector< unsigned > &precision)
set fixed point precision
unsigned long getCompleteHitPattern(unsigned isector, const CDCTriggerTrack &track, const bool neurotrackinputmode)
Get complete hit pattern of neurotrack.
void getEventTime(unsigned isector, const CDCTriggerTrack &track, std::string et_option, const bool)
Read out the event time and store it.
std::vector< float > runMLP(unsigned isector, const std::vector< float > &input)
Run an expert MLP.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
bool requireRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, const std::string &namedRelation="") const
Produce error if no relation from this array to 'toArray' has been registered.
T * appendNew()
Construct a new T object at the end of the array.
int getEntries() const
Get the number of objects in the array.
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.