126#include "TRestDetectorSignalToHitsProcess.h"
128#include "TRestDetectorSetup.h"
188 fGas = GetMetadata<TRestDetectorGas>();
189 if (
fGas !=
nullptr) {
191 RESTError <<
"A TRestDetectorGas definition was found but REST was not linked to Garfield libraries."
194 <<
"Please, remove the TRestDetectorGas definition, and add gas parameters inside the process "
195 "TRestDetectorSignalToHitsProcess"
198 if (!this->
GetError()) this->
SetError(
"Attempt to use TRestDetectorGas without Garfield");
214 fReadout = GetMetadata<TRestDetectorReadout>();
217 if (!this->
GetError()) this->
SetError(
"The readout was not properly initialized.");
234 RESTDebug <<
"TRestDetectorSignalToHitsProcess. Event id : " <<
fHitsEvent->GetID() <<
RESTendl;
237 Int_t numberOfSignals =
fSignalEvent->GetNumberOfSignals();
239 if (numberOfSignals == 0)
return nullptr;
241 Int_t planeID, readoutChannel = -1, readoutModule;
242 for (
int i = 0; i < numberOfSignals; i++) {
244 Int_t signalID = sgnl->GetSignalID();
247 cout <<
"Searching readout coordinates for signal ID : " << signalID << endl;
249 fReadout->GetPlaneModuleChannel(signalID, planeID, readoutModule, readoutChannel);
251 if (readoutChannel == -1) {
261 Double_t fieldZDirection = plane->
GetNormal().Z();
264 Double_t x = plane->
GetX(readoutModule, readoutChannel);
265 Double_t y = plane->
GetY(readoutModule, readoutChannel);
267 REST_HitType type = XYZ;
269 if (TMath::IsNaN(x)) {
272 }
else if (TMath::IsNaN(y)) {
278 Double_t hitTime = sgnl->GetMaxPeakTime();
282 cout <<
"Distance to plane : " << distanceToPlane << endl;
284 Double_t z = zPosition + fieldZDirection * distanceToPlane;
286 Double_t energy = sgnl->GetMaxPeakValue();
289 cout <<
"Adding hit. Time : " << hitTime <<
" x : " << x <<
" y : " << y <<
" z : " << z
290 <<
" Energy : " << energy << endl;
293 }
else if (
fMethod ==
"tripleMax") {
294 Int_t bin = sgnl->GetMaxIndex();
295 int binprev = (bin - 1) < 0 ? bin : bin - 1;
296 int binnext = (bin + 1) > sgnl->GetNumberOfPoints() - 1 ? bin : bin + 1;
298 Double_t hitTime = sgnl->GetTime(bin);
299 Double_t energy = sgnl->GetData(bin);
302 Double_t z = zPosition + fieldZDirection * distanceToPlane;
306 hitTime = sgnl->GetTime(binprev);
307 energy = sgnl->GetData(binprev);
310 z = zPosition + fieldZDirection * distanceToPlane;
314 hitTime = sgnl->GetTime(binnext);
315 energy = sgnl->GetData(binnext);
318 z = zPosition + fieldZDirection * distanceToPlane;
323 cout <<
"Distance to plane : " << distanceToPlane << endl;
324 cout <<
"Adding hit. Time : " << hitTime <<
" x : " << x <<
" y : " << y <<
" z : " << z
325 <<
" Energy : " << energy << endl;
327 }
else if (
fMethod ==
"tripleMaxAverage") {
328 Int_t bin = sgnl->GetMaxIndex();
329 int binprev = (bin - 1) < 0 ? bin : bin - 1;
330 int binnext = (bin + 1) > sgnl->GetNumberOfPoints() - 1 ? bin : bin + 1;
332 Double_t hitTime = sgnl->GetTime(bin);
333 Double_t energy1 = sgnl->GetData(bin);
336 Double_t z1 = zPosition + fieldZDirection * distanceToPlane;
338 hitTime = sgnl->GetTime(binprev);
339 Double_t energy2 = sgnl->GetData(binprev);
342 Double_t z2 = zPosition + fieldZDirection * distanceToPlane;
344 hitTime = sgnl->GetTime(binnext);
345 Double_t energy3 = sgnl->GetData(binnext);
348 Double_t z3 = zPosition + fieldZDirection * distanceToPlane;
350 Double_t eTot = energy1 + energy2 + energy3;
352 Double_t zAvg = ((z1 * energy1) + (z2 * energy2) + (z3 * energy3)) / eTot;
354 Double_t eAvg = eTot / 3.0;
359 cout <<
"Distance to plane: " << distanceToPlane << endl;
360 cout <<
"Adding hit. Time : " << hitTime <<
" x : " << x <<
" y : " << y <<
" z : " << zAvg
361 <<
" Energy : " << eAvg << endl;
362 cout <<
"z1, z2, z3 = " << z1 <<
", " << z2 <<
", " << z3 << endl;
363 cout <<
"E1, E2, E3 = " << energy1 <<
", " << energy2 <<
", " << energy3 << endl;
366 }
else if (
fMethod ==
"gaussFit") {
367 TVector2 gaussFit = sgnl->GetMaxGauss();
369 Double_t hitTime = 0;
371 if (gaussFit.X() >= 0.0) {
372 hitTime = gaussFit.X();
374 z = zPosition + fieldZDirection * distanceToPlane;
376 Double_t energy = -1.0;
377 if (gaussFit.Y() >= 0.0) {
378 energy = gaussFit.Y();
382 cout <<
"Signal event : " << sgnl->GetSignalID()
383 <<
"--------------------------------------------------------" << endl;
384 cout <<
"GausFit : time bin " << gaussFit.X() <<
" and energy : " << gaussFit.Y() << endl;
385 cout <<
"Signal to hit info : zPosition : " << zPosition
386 <<
"; fieldZDirection : " << fieldZDirection <<
" and driftV : " <<
fDriftVelocity
388 cout <<
"Adding hit. Time : " << hitTime <<
" x : " << x <<
" y : " << y <<
" z : " << z
389 <<
" Energy : " << energy << endl;
394 }
else if (
fMethod ==
"landauFit") {
395 TVector2 landauFit = sgnl->GetMaxLandau();
397 Double_t hitTime = 0;
399 if (landauFit.X() >= 0.0) {
400 hitTime = landauFit.X();
402 z = zPosition + fieldZDirection * distanceToPlane;
404 Double_t energy = -1.0;
405 if (landauFit.Y() >= 0.0) {
406 energy = landauFit.Y();
410 cout <<
"Signal event : " << sgnl->GetSignalID()
411 <<
"--------------------------------------------------------" << endl;
412 cout <<
"landauFit : time bin " << landauFit.X() <<
" and energy : " << landauFit.Y() << endl;
413 cout <<
"Signal to hit info : zPosition : " << zPosition
414 <<
"; fieldZDirection : " << fieldZDirection <<
" and driftV : " <<
fDriftVelocity
416 cout <<
"Adding hit. Time : " << hitTime <<
" x : " << x <<
" y : " << y <<
" z : " << z
417 <<
" Energy : " << energy << endl;
422 }
else if (
fMethod ==
"agetFit") {
423 TVector2 agetFit = sgnl->GetMaxAget();
425 Double_t hitTime = 0;
427 if (agetFit.X() >= 0.0) {
428 hitTime = agetFit.X();
430 z = zPosition + fieldZDirection * distanceToPlane;
432 Double_t energy = -1.0;
433 if (agetFit.Y() >= 0.0) {
434 energy = agetFit.Y();
438 cout <<
"Signal event : " << sgnl->GetSignalID()
439 <<
"--------------------------------------------------------" << endl;
440 cout <<
"agetFit : time bin " << agetFit.X() <<
" and energy : " << agetFit.Y() << endl;
441 cout <<
"Signal to hit info : zPosition : " << zPosition
442 <<
"; fieldZDirection : " << fieldZDirection <<
" and driftV : " <<
fDriftVelocity
444 cout <<
"Adding hit. Time : " << hitTime <<
" x : " << x <<
" y : " << y <<
" z : " << z
445 <<
" Energy : " << energy << endl;
450 }
else if (
fMethod ==
"qCenter") {
451 Double_t energy_signal = 0;
452 Double_t distanceToPlane = 0;
454 for (
int j = 0; j < sgnl->GetNumberOfPoints(); j++) {
455 Double_t energy_point = sgnl->GetData(j);
456 energy_signal += energy_point;
457 distanceToPlane += sgnl->GetTime(j) *
fDriftVelocity * energy_point;
459 Double_t energy = energy_signal / sgnl->GetNumberOfPoints();
461 Double_t z = zPosition + fieldZDirection * (distanceToPlane / energy_signal);
464 for (
int j = 0; j < sgnl->GetNumberOfPoints(); j++) {
465 Double_t energy = sgnl->GetData(j);
470 cout <<
"Time : " << sgnl->GetTime(j) <<
" Drift velocity : " <<
fDriftVelocity << endl;
471 cout <<
"Distance to plane : " << distanceToPlane << endl;
474 Double_t z = zPosition + fieldZDirection * distanceToPlane;
477 cout <<
"Adding hit. Time : " << sgnl->GetTime(j) <<
" x : " << x <<
" y : " << y
478 <<
" z : " << z << endl;
482 }
else if (
fMethod ==
"intwindow") {
483 Int_t nPoints = sgnl->GetNumberOfPoints();
484 std::map<int, std::pair<int, double> > windowMap;
485 for (
int j = 0; j < nPoints; j++) {
486 int index = sgnl->GetTime(j) / fIntWindow;
487 auto it = windowMap.find(index);
488 if (it != windowMap.end()) {
490 it->second.second += sgnl->GetData(j);
492 windowMap[index] = std::make_pair(1, sgnl->GetData(j));
496 for (
const auto& [index, pair] : windowMap) {
497 Double_t hitTime = index * fIntWindow + fIntWindow / 2.;
498 Double_t energy = pair.second / pair.first;
499 if (energy < fThreshold)
continue;
500 RESTDebug <<
"TimeBin " << index <<
" Time " << hitTime <<
" Charge: " << energy
501 <<
" Thr: " << (fThreshold) <<
RESTendl;
503 Double_t z = zPosition + fieldZDirection * distanceToPlane;
505 RESTDebug <<
"Time : " << hitTime <<
" Drift velocity : " <<
fDriftVelocity
506 <<
"\nDistance to plane : " << distanceToPlane <<
RESTendl;
507 RESTDebug <<
"Adding hit. Time : " << hitTime <<
" x : " << x <<
" y : " << y <<
" z : " << z
513 string errMsg =
"The method " + (string)
fMethod +
" is not implemented!";
518 RESTDebug <<
"TRestDetectorSignalToHitsProcess. Hits added : " <<
fHitsEvent->GetNumberOfHits()
520 RESTDebug <<
"TRestDetectorSignalToHitsProcess. Hits total energy : " <<
fHitsEvent->GetEnergy()
531 ". Failed to find readout positions in channel to hit conversion.";
virtual void SetElectricField(double value)
Sets the electric field. Must be given in V/mm.
virtual Double_t GetElectricField() const
Returns the electric field in V/mm.
void SetPressure(Double_t pressure) override
Defines the pressure of the gas.
Double_t GetDriftVelocity(Double_t E)
It returns the drift velocity in cm/us for a given electric field in V/cm.
virtual void PrintEvent() const
void AddHit(Double_t x, Double_t y, Double_t z, Double_t en, Double_t t=0, REST_HitType type=XYZ)
Adds a new hit to this event.
TVector2 GetSize() const
Returns the module size (x, y) in mm.
TVector2 GetPlaneCoordinates(const TVector2 &p)
TRestDetectorReadoutModule * GetModuleByID(Int_t modID)
Returns a pointer to a module using its internal module id.
TVector3 GetNormal() const
Returns a TVector3 with a vector normal to the readout plane.
TVector3 GetPosition() const
Returns a TVector3 with the readout plane position.
Double_t GetX(Int_t modID, Int_t chID)
Returns the X coordinate of a given channel in a given module using their internal module and channel...
Double_t GetY(Int_t modID, Int_t chID)
Returns the Y coordinate of a given channel in a given module using their internal module and channel...
TRestDetectorReadoutPlane * GetReadoutPlaneWithID(int id)
Returns a pointer to the readout plane by ID.
A process to transform a daq channel and physical time to spatial coordinates.
Double_t fDriftVelocity
The drift velocity in standard REST units (mm/us).
void InitProcess() override
Process initialization. Observable names are interpreted and auxiliar observable members,...
TRestDetectorHitsEvent * fHitsEvent
A pointer to the specific TRestDetectorHitsEvent output.
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
The main processing event function.
Double_t fGasPressure
The gas pressure in atm. Only relevant if TRestDetectorGas is used.
TRestDetectorGas * fGas
A pointer to the detector gas definition accessible to TRestRun.
~TRestDetectorSignalToHitsProcess()
Default destructor.
TRestDetectorSignalToHitsProcess()
Default constructor.
void Initialize() override
Function to initialize input/output event members and define the section name.
void LoadDefaultConfig()
Function to load the default config in absence of RML input.
Double_t fElectricField
The electric field in standard REST units (V/mm). Only relevant if TRestDetectorGas is used.
TString fMethod
The method used to transform the signal points to hits.
TRestDetectorSignalEvent * fSignalEvent
A pointer to the specific TRestDetectorHitsEvent input.
TRestDetectorReadout * fReadout
A pointer to the detector readout definition accesible to TRestRun.
A base class for any REST event.
@ REST_Extreme
show everything
@ REST_Debug
+show the defined debug messages
std::string IntegerToString(Int_t n, std::string format="%d")
Gets a string from an integer.