9 #include <svd/modules/svdReconstruction/SVDNNShapeReconstructorModule.h>
11 #include <framework/datastore/DataStore.h>
12 #include <framework/datastore/StoreArray.h>
13 #include <framework/logging/Logger.h>
15 #include <mdst/dataobjects/MCParticle.h>
16 #include <svd/dataobjects/SVDTrueHit.h>
17 #include <svd/dataobjects/SVDShaperDigit.h>
18 #include <svd/dataobjects/SVDRecoDigit.h>
19 #include <mva/dataobjects/DatabaseRepresentationOfWeightfile.h>
21 #include <svd/reconstruction/NNWaveFitTool.h>
41 B2DEBUG(200,
"Now in SVDNNShapeReconstructorModule ctor");
43 setDescription(
"Reconstruct signals on SVD strips.");
44 setPropertyFlags(c_ParallelProcessingCertified);
47 addParam(
"Digits", m_storeShaperDigitsName,
48 "Shaperdigits collection name",
string(
""));
49 addParam(
"RecoDigits", m_storeRecoDigitsName,
50 "RecoDigits collection name",
string(
""));
51 addParam(
"TrueHits", m_storeTrueHitsName,
52 "TrueHits collection name",
string(
""));
53 addParam(
"MCParticles", m_storeMCParticlesName,
54 "MCParticles collection name",
string(
""));
55 addParam(
"WriteRecoDigits", m_writeRecoDigits,
56 "Write RecoDigits to output?", m_writeRecoDigits);
57 addParam(
"SVDEventInfo", m_svdEventInfoName,
58 "SVDEventInfo name",
string(
""));
60 addParam(
"TimeFitterName", m_timeFitterName,
61 "Name of time fitter data file",
string(
"SVDTimeNet_6samples"));
62 addParam(
"CalibratePeak", m_calibratePeak,
"Use calibrattion (vs. default) for peak widths and positions",
bool(
false));
64 addParam(
"ZeroSuppressionCut", m_cutAdjacent,
"Zero-suppression cut on digits",
68 void SVDNNShapeReconstructorModule::initialize()
76 if (!m_writeRecoDigits)
84 m_storeSVDEvtInfo.isRequired();
86 if (!m_storeSVDEvtInfo.isOptional(m_svdEventInfoName)) m_svdEventInfoName =
"SVDEventInfoSim";
87 m_storeSVDEvtInfo.isRequired(m_svdEventInfoName);
89 RelationArray relRecoDigitShaperDigits(storeRecoDigits, storeShaperDigits);
90 RelationArray relRecoDigitTrueHits(storeRecoDigits, storeTrueHits);
91 RelationArray relRecoDigitMCParticles(storeRecoDigits, storeMCParticles);
92 RelationArray relShaperDigitTrueHits(storeShaperDigits, storeTrueHits);
93 RelationArray relShaperDigitMCParticles(storeShaperDigits, storeMCParticles);
95 if (!m_writeRecoDigits)
106 m_storeRecoDigitsName = storeRecoDigits.
getName();
107 m_storeShaperDigitsName = storeShaperDigits.
getName();
108 m_storeTrueHitsName = storeTrueHits.
getName();
109 m_storeMCParticlesName = storeMCParticles.
getName();
111 m_relRecoDigitShaperDigitName = relRecoDigitShaperDigits.
getName();
112 m_relRecoDigitTrueHitName = relRecoDigitTrueHits.
getName();
113 m_relRecoDigitMCParticleName = relRecoDigitMCParticles.
getName();
114 m_relShaperDigitTrueHitName = relShaperDigitTrueHits.
getName();
115 m_relShaperDigitMCParticleName = relShaperDigitMCParticles.
getName();
117 B2INFO(
" 1. COLLECTIONS:");
118 B2INFO(
" --> MCParticles: " << m_storeMCParticlesName);
119 B2INFO(
" --> Digits: " << m_storeShaperDigitsName);
120 B2INFO(
" --> RecoDigits: " << m_storeRecoDigitsName);
121 B2INFO(
" --> TrueHits: " << m_storeTrueHitsName);
122 B2INFO(
" --> DigitMCRel: " << m_relShaperDigitMCParticleName);
123 B2INFO(
" --> RecoDigitMCRel: " << m_relRecoDigitMCParticleName);
124 B2INFO(
" --> RecoDigitDigitRel: " << m_relRecoDigitShaperDigitName);
125 B2INFO(
" --> DigitTrueRel: " << m_relShaperDigitTrueHitName);
126 B2INFO(
" --> RecoDigitTrueRel: " << m_relRecoDigitTrueHitName);
127 B2INFO(
" --> Save RecoDigits? " << (m_writeRecoDigits ?
"Y" :
"N"));
128 B2INFO(
" 2. CALIBRATION:");
129 B2INFO(
" --> Time NN: " << m_timeFitterName);
135 m_fitter.setNetwrok(dbXml->m_data);
138 void SVDNNShapeReconstructorModule::createRelationLookup(
const RelationArray& relation,
143 if (!relation)
return;
145 lookup.resize(digits);
146 for (
const auto& element : relation) {
147 lookup[element.getFromIndex()] = &element;
151 void SVDNNShapeReconstructorModule::fillRelationMap(
const RelationLookup& lookup,
152 std::map<unsigned int, float>& relation,
unsigned int index)
155 if (!lookup.empty() && lookup[index]) {
157 const unsigned int size = element.getSize();
159 for (
unsigned int i = 0; i < size; ++i) {
162 if (element.getWeight(i) < 0)
continue;
163 relation[element.getToIndex(i)] += element.getWeight(i);
168 void SVDNNShapeReconstructorModule::event()
173 if (!storeShaperDigits || !storeShaperDigits.
getEntries() || !m_storeSVDEvtInfo.isValid())
return;
175 SVDModeByte modeByte = m_storeSVDEvtInfo->getModeByte();
177 size_t nDigits = storeShaperDigits.
getEntries();
178 B2DEBUG(90,
"Initial size of StoreDigits array: " << nDigits);
183 RelationArray relShaperDigitMCParticle(storeShaperDigits, storeMCParticles, m_relShaperDigitMCParticleName);
184 RelationArray relShaperDigitTrueHit(storeShaperDigits, storeTrueHits, m_relShaperDigitTrueHitName);
187 storeRecoDigits.
clear();
189 RelationArray relRecoDigitMCParticle(storeRecoDigits, storeMCParticles,
190 m_relRecoDigitMCParticleName);
191 if (relRecoDigitMCParticle) relRecoDigitMCParticle.
clear();
193 RelationArray relRecoDigitShaperDigit(storeRecoDigits, storeShaperDigits,
194 m_relRecoDigitShaperDigitName);
195 if (relRecoDigitShaperDigit) relRecoDigitShaperDigit.
clear();
197 RelationArray relRecoDigitTrueHit(storeRecoDigits, storeTrueHits,
198 m_relRecoDigitTrueHitName);
199 if (relRecoDigitTrueHit) relRecoDigitTrueHit.
clear();
202 createRelationLookup(relShaperDigitMCParticle, m_mcRelation, nDigits);
203 createRelationLookup(relShaperDigitTrueHit, m_trueRelation, nDigits);
209 vector<pair<unsigned short, unsigned short> > sensorDigits;
210 VxdID lastSensorID(0);
211 size_t firstSensorDigit = 0;
212 for (
size_t iDigit = 0; iDigit < nDigits; ++iDigit) {
216 if (sensorID != lastSensorID) {
217 sensorDigits.push_back(make_pair(firstSensorDigit, iDigit));
218 firstSensorDigit = iDigit;
219 lastSensorID = sensorID;
223 sensorDigits.push_back(make_pair(firstSensorDigit, nDigits));
226 for (
auto id_indices : sensorDigits) {
228 unsigned int firstDigit = id_indices.first;
229 unsigned int lastDigit = id_indices.second;
231 const SVDShaperDigit& exampleDigit = *storeShaperDigits[firstDigit];
237 B2DEBUG(300,
"Reconstructing digits " << firstDigit <<
" to " << lastDigit);
238 for (
size_t iDigit = firstDigit; iDigit < lastDigit; ++iDigit) {
241 unsigned short stripNo = shaperDigit.
getCellID();
242 bool validDigit =
true;
243 const double triggerBinSep = 4 * 1.96516;
244 double apvPhase = triggerBinSep * (0.5 +
static_cast<int>(modeByte.
getTriggerBin()));
247 float stripNoiseADU = m_noiseCal.getNoise(sensorID, isU, stripNo);
251 double stripSignalWidth = 270;
252 double stripT0 = isU ? 2.5 : -2.2;
253 if (m_calibratePeak) {
254 stripSignalWidth = 1.988 * m_pulseShapeCal.getWidth(sensorID, isU, stripNo);
255 stripT0 = m_pulseShapeCal.getPeakTime(sensorID, isU, stripNo)
256 - 0.25 * stripSignalWidth;
259 B2DEBUG(300,
"Strip parameters: stripNoiseADU: " << stripNoiseADU <<
260 " Width: " << stripSignalWidth <<
266 transform(samples.begin(), samples.end(), normedSamples.begin(),
267 bind2nd(divides<float>(), stripNoiseADU));
269 validDigit = validDigit &&
pass3Samples(normedSamples, m_cutAdjacent);
272 zeroSuppress(normedSamples, m_cutAdjacent);
279 os <<
"Input to NNFitter: iDigit = " << iDigit << endl <<
"Samples: ";
280 copy(normedSamples.begin(), normedSamples.end(), ostream_iterator<double>(os,
" "));
282 std::shared_ptr<nnFitterBinData> pStrip = m_fitter.getFit(normedSamples, stripSignalWidth);
283 os <<
"Output from NNWaveFitter: " << endl;
284 copy(pStrip->begin(), pStrip->end(), ostream_iterator<double>(os,
" "));
288 B2DEBUG(200, os.str());
290 double stripTime, stripTimeError;
291 tie(stripTime, stripTimeError) = fitTool.
getTimeShift(*pStrip);
293 double stripAmplitude, stripAmplitudeError, stripChi2;
294 tie(stripAmplitude, stripAmplitudeError, stripChi2) =
297 stripAmplitude = m_pulseShapeCal.getChargeFromADC(sensorID, isU, stripNo, stripAmplitude * stripNoiseADU);
298 stripAmplitudeError = m_pulseShapeCal.getChargeFromADC(sensorID, isU, stripNo, stripAmplitudeError * stripNoiseADU);
299 B2DEBUG(200,
"RecoDigit " << iDigit <<
" Noise: " << m_pulseShapeCal.getChargeFromADC(sensorID, isU, stripNo, stripNoiseADU)
300 <<
" Time: " << stripTime <<
" +/- " << stripTimeError
301 <<
" Amplitude: " << stripAmplitude <<
" +/- " << stripAmplitudeError
302 <<
" Chi2: " << stripChi2
306 map<unsigned int, float> mc_relations;
307 map<unsigned int, float> truehit_relations;
308 vector<pair<unsigned int, float> > digit_weights;
309 digit_weights.reserve(1);
312 fillRelationMap(m_mcRelation, mc_relations, iDigit);
313 fillRelationMap(m_trueRelation, truehit_relations, iDigit);
315 digit_weights.emplace_back(iDigit, 1.0);
318 int recoDigitIndex = storeRecoDigits.
getEntries();
321 stripAmplitudeError, stripTime, stripTimeError, *pStrip, stripChi2)
325 if (!mc_relations.empty()) {
326 relRecoDigitMCParticle.
add(recoDigitIndex, mc_relations.begin(), mc_relations.end());
328 if (!truehit_relations.empty()) {
329 relRecoDigitTrueHit.
add(recoDigitIndex, truehit_relations.begin(), truehit_relations.end());
331 relRecoDigitShaperDigit.
add(recoDigitIndex, digit_weights.begin(), digit_weights.end());
336 B2DEBUG(100,
"Number of RecoDigits: " << storeRecoDigits.
getEntries());
Class for accessing objects in the database.
Low-level class to create/modify relations between StoreArrays.
void add(index_type from, index_type to, weight_type weight=1.0)
Add a new element to the relation.
void clear() override
Clear all elements from the relation.
Class to store a single element of a relation.
Class to store SVD mode information.
baseType getTriggerBin() const
Get the triggerBin id.
The SVD ShaperDigit class.
VxdID getSensorID() const
Get the sensor ID.
APVFloatSamples getSamples() const
Get array of samples.
short int getCellID() const
Get strip ID.
bool isUStrip() const
Get strip direction.
The SVD NNShapeReconstructor.
std::vector< const RelationElement * > RelationLookup
Container for a RelationArray Lookup table.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
const std::string & getName() const
Return name under which the object is saved in the DataStore.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Accessor to arrays stored in the data store.
T * appendNew()
Construct a new T object at the end of the array.
int getEntries() const
Get the number of objects in the array.
void clear() override
Delete all entries in this array.
Class to uniquely identify a any structure of the PXD and SVD.
void setSegmentNumber(baseType segment)
Set the sensor segment.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Namespace to encapsulate code needed for simulation and reconstrucion of the SVD.
std::array< apvSampleBaseType, nAPVSamples > apvSamples
vector od apvSample BaseType objects
bool pass3Samples(const T &a, double thr)
pass 3-samples
Abstract base class for different kinds of events.