SND@LHC Software
Loading...
Searching...
No Matches
MuFilterHit.cxx
Go to the documentation of this file.
1#include "MuFilterHit.h"
2#include "MuFilter.h"
3#include "ShipUnit.h"
4#include "TROOT.h"
5#include "FairRunSim.h"
6#include "TGeoNavigator.h"
7#include "TGeoManager.h"
8#include "TGeoBBox.h"
10#include <TRandom.h>
11#include <iomanip>
12#include <string.h>
13#include <stdio.h>
14#include <stdlib.h>
15
16
17// ----- Default constructor -------------------------------------------
19 : SndlhcHit()
20{
21 flag = true;
22 for (Int_t i=0;i<16;i++){fMasked[i]=kFALSE;}
23}
24// ----- Standard constructor ------------------------------------------
26 : SndlhcHit(detID)
27{
28 flag = true;
29 for (Int_t i=0;i<16;i++){fMasked[i]=kFALSE;}
30}
31MuFilterHit::MuFilterHit(Int_t detID,Int_t nP,Int_t nS)
32 : SndlhcHit(detID,nP,nS)
33{
34 flag = true;
35 for (Int_t i=0;i<16;i++){
36 fMasked[i]=kFALSE;
37 signals[i] = -999;
38 times[i] = -999;
39 fDaqID[i] = -1;
40 }
41}
42
43
44// ----- constructor from MuFilterPoint ------------------------------------------
45MuFilterHit::MuFilterHit(Int_t detID, std::vector<MuFilterPoint*> V)
46 : SndlhcHit()
47{
48 MuFilter* MuFilterDet = dynamic_cast<MuFilter*> (gROOT->GetListOfGlobals()->FindObject("MuFilter"));
49 // get parameters from the MuFilter detector for simulating the digitized information
50 nSiPMs = MuFilterDet->GetnSiPMs(detID);
51 nSides = MuFilterDet->GetnSides(detID);
52
53 Float_t timeResol = MuFilterDet->GetConfParF("MuFilter/timeResol");
54
55 Float_t attLength=0;
56 Float_t siPMcalibration=0;
57 Float_t siPMcalibrationS=0;
58 Float_t propspeed =0;
59 if (floor(detID/10000)==3) {
60 if (nSides==2){attLength = MuFilterDet->GetConfParF("MuFilter/DsAttenuationLength");}
61 else {attLength = MuFilterDet->GetConfParF("MuFilter/DsTAttenuationLength");}
62 siPMcalibration = MuFilterDet->GetConfParF("MuFilter/DsSiPMcalibration");
63 propspeed = MuFilterDet->GetConfParF("MuFilter/DsPropSpeed");
64 }
65 else {
66 if (floor(detID/10000)==1 && nSides==1){
67 // top readout with mirror on bottom
68 attLength = 2*MuFilterDet->GetConfParF("MuFilter/VTAttenuationLength");
69 }
70 else {attLength = MuFilterDet->GetConfParF("MuFilter/VandUpAttenuationLength");}
71 siPMcalibration = MuFilterDet->GetConfParF("MuFilter/VandUpSiPMcalibrationL");
72 siPMcalibrationS = MuFilterDet->GetConfParF("MuFilter/VandUpSiPMcalibrationS");
73 propspeed = MuFilterDet->GetConfParF("MuFilter/VandUpPropSpeed");
74 }
75
76 for (unsigned int j=0; j<16; ++j){
77 signals[j] = -1;
78 times[j] =-1;
79 }
80 LOG(DEBUG) << "detid "<<detID<< " size "<<nSiPMs<< " side "<<nSides;
81
82 fDetectorID = detID;
83 Float_t signalLeft = 0;
84 Float_t signalRight = 0;
85 Float_t earliestToAL = 1E20;
86 Float_t earliestToAR = 1E20;
87 for(auto p = std::begin(V); p!= std::end(V); ++p) {
88
89 Double_t signal = (*p)->GetEnergyLoss();
90
91 // Find distances from MCPoint centre to ends of bar
92 TVector3 vLeft,vRight;
93 TVector3 impact((*p)->GetX(),(*p)->GetY() ,(*p)->GetZ() );
94 MuFilterDet->GetPosition(fDetectorID,vLeft, vRight);
95 Double_t distance_Left = (vLeft-impact).Mag();
96 Double_t distance_Right = (vRight-impact).Mag();
97 // Simple model: divide signal between nSides
98 signalLeft+=signal/nSides*TMath::Exp(-distance_Left/attLength);
99 signalRight+=signal/nSides*TMath::Exp(-distance_Right/attLength);
100
101 // for the timing, find earliest particle and smear with time resolution
102 Double_t ptime = (*p)->GetTime();
103 Double_t t_Left = ptime + distance_Left/propspeed;
104 Double_t t_Right = ptime + distance_Right/propspeed;
105 if ( t_Left <earliestToAL){earliestToAL = t_Left ;}
106 if ( t_Right <earliestToAR){earliestToAR = t_Right ;}
107 }
108 // shortSiPM = {3,6,11,14,19,22,27,30,35,38,43,46,51,54,59,62,67,70,75,78}; - counting from 1!
109 // In the SndlhcHit class the 'signals' array starts from 0.
110 for (unsigned int j=0; j<nSiPMs; ++j){
111 if ( floor(detID/10000)==2 && (j==2 or j==5)){ // only US has small SiPMs
112 signals[j] = signalLeft/float(nSiPMs) * siPMcalibrationS; // most simplest model, divide signal individually. Small SiPMS special: set signal to zero
113 times[j] = gRandom->Gaus(earliestToAL, timeResol);
114 }else{
115 signals[j] = signalLeft/float(nSiPMs) * siPMcalibration; // most simplest model, divide signal individually.
116 times[j] = gRandom->Gaus(earliestToAL, timeResol);
117 }
118 if (nSides>1){
119 signals[j+nSiPMs] = signalRight/float(nSiPMs) * siPMcalibration; // most simplest model, divide signal individually.
120 times[j+nSiPMs] = gRandom->Gaus(earliestToAR, timeResol);
121 }
122 }
123 flag = true;
124 for (Int_t i=0;i<16;i++){fMasked[i]=kFALSE;}
125 LOG(DEBUG) << "signal created";
126}
127
128// ----- Destructor ----------------------------------------------------
130// -------------------------------------------------------------------------
131
132// ----- Public method GetEnergy -------------------------------------------
133Float_t MuFilterHit::GetEnergy(Bool_t use_small_sipms)
134{
135 // to be calculated from digis and calibration constants, missing!
136 Float_t E = 0;
137 for (unsigned int j=0; j<nSiPMs; ++j){
138 if (!use_small_sipms && isShort(j)) continue; // remove small SiPMs
139 E+=signals[j];
140 if (nSides>1){ E+=signals[j+nSiPMs];}
141 }
142 return E;
143}
144
146 if ( (GetSystem()==3&&fDetectorID%1000>59) ||
147 (GetSystem()==1&&GetPlane()==2) ) {
148 return kTRUE;
149 }
150 else{return kFALSE;}
151}
152
154 // only US has short SiPMs
155 if (GetSystem()==2 && (i%8==2 || i%8==5)) {return kTRUE;}
156 else{return kFALSE;}
157}
158
159// ----- Public method Get List of signals -------------------------------------------
160std::map<Int_t,Float_t> MuFilterHit::GetAllSignals(Bool_t mask, Bool_t positive, Bool_t use_small_sipms, Bool_t use_calibration)
161{
162 std::map<Int_t,Float_t> allSignals;
163
164 for (unsigned int s=0; s<nSides; ++s){
165 for (unsigned int j=0; j<nSiPMs; ++j){
166 unsigned int channel = j+s*nSiPMs;
167 if (signals[channel]<-900){continue;}
168 if (signals[channel]> 0 || !positive){
169 if (!fMasked[channel] || !mask){
170 if (!isShort(channel) || use_small_sipms){
171 if (use_calibration){
172 /*
173 * With calibration: divide signals by SiPM-specific calibration constants,
174 * apply sub-system wide constant offset,
175 * then rescale to align the signal of 1 MIP with a value of 1.
176 * To disregard the constant offset, either supply a constants file where it is set to 0,
177 * or use the followign formula: allSignals[channel] = signals[channel]/calibrationConstant;
178 */
179 float calibrationConstant = SiPM_qdc_calibration_constants[fDetectorID*100+channel];
180 float constantOffset = SiPM_qdc_calibration_constants[fDetectorID/10000]; // get sub-system wide offset (1-VS, 2-US, 3-DS)
181 if (calibrationConstant > 0.){ // non-positive constant = problem
182 allSignals[channel] = (signals[channel]/calibrationConstant + constantOffset) / (1 + constantOffset);
183 }
184 }
185 else{ // no calibration: raw signals
186 allSignals[channel] = signals[channel];
187 }
188 }
189 }
190 }
191 }
192 }
193 return allSignals;
194}
195
196// ----- Public method Get List of time measurements -------------------------------------------
197std::map<Int_t,Float_t> MuFilterHit::GetAllTimes(Bool_t mask,Bool_t positive,Bool_t use_small_sipms)
198{
199 std::map<Int_t,Float_t> allTimes;
200 for (unsigned int s=0; s<nSides; ++s){
201 for (unsigned int j=0; j<nSiPMs; ++j){
202 unsigned int channel = j+s*nSiPMs;
203 if (signals[channel]> 0 || !positive){
204 if (!fMasked[channel] || !mask){
205 if (!isShort(channel) || use_small_sipms){
206 allTimes[channel] = times[channel];
207 }
208 }
209 }
210 }
211 }
212 return allTimes;
213}
214
215// ----- Public method Get time difference mean Left - mean Right -----------------
216Float_t MuFilterHit::GetDeltaT(Bool_t mask,Bool_t positive,Bool_t use_small_sipms)
217// based on mean TDC measured on Left and Right
218{
219 Float_t mean[] = {0,0};
220 Int_t count[] = {0,0};
221 Float_t dT = -999.;
222 for (unsigned int s=0; s<nSides; ++s){
223 for (unsigned int j=0; j<nSiPMs; ++j){
224 unsigned int channel = j+s*nSiPMs;
225 if (signals[channel]> 0 || !positive){
226 if (!fMasked[channel] || !mask){
227 if (!isShort(channel) || use_small_sipms){
228 mean[s] += times[channel];
229 count[s] += 1;
230 }
231 }
232 }
233 }
234 }
235 if (count[0]>0 && count[1]>0) {
236 dT = mean[0]/count[0] - mean[1]/count[1];
237 }
238 return dT;
239}
240Float_t MuFilterHit::GetFastDeltaT(Bool_t mask,Bool_t positive,Bool_t use_small_sipms)
241// based on fastest (earliest) TDC measured on Left and Right
242{
243 Float_t first[] = {1E20,1E20};
244 Float_t dT = -999.;
245 for (unsigned int s=0; s<nSides; ++s){
246 for (unsigned int j=0; j<nSiPMs; ++j){
247 unsigned int channel = j+s*nSiPMs;
248 if (signals[channel]> 0 || !positive){
249 if (!fMasked[channel] || !mask){
250 if (!isShort(channel) || use_small_sipms){
251 if (times[channel]<first[s]) {first[s] = times[channel];}
252 }
253 }
254 }
255 }
256 }
257 if (first[0]<1E10 && first[1]<1E10) {
258 dT = first[0] - first[1];
259 }
260 return dT;
261}
262
263
264// ----- Public method Get mean time -----------------
265Float_t MuFilterHit::GetImpactT(Bool_t mask,Bool_t positive,Bool_t use_small_sipms)
266{
267 Float_t mean[] = {0,0};
268 Int_t count[] = {0,0};
269 Float_t dT = -999.;
270 Float_t dL;
271 MuFilter* MuFilterDet = dynamic_cast<MuFilter*> (gROOT->GetListOfGlobals()->FindObject("MuFilter"));
272 if (GetSystem()==3) {
273 dL = MuFilterDet->GetConfParF("MuFilter/DownstreamBarX") / MuFilterDet->GetConfParF("MuFilter/DsPropSpeed");}
274 else if (GetSystem()==2) {
275 dL = MuFilterDet->GetConfParF("MuFilter/UpstreamBarX") / MuFilterDet->GetConfParF("MuFilter/VandUpPropSpeed");}
276 else {
277 dL = MuFilterDet->GetConfParF("MuFilter/VetoBarX") / MuFilterDet->GetConfParF("MuFilter/VandUpPropSpeed");}
278
279 for (unsigned int s=0; s<nSides; ++s){
280 for (unsigned int j=0; j<nSiPMs; ++j){
281 unsigned int channel = j+s*nSiPMs;
282 if (signals[channel]> 0 || !positive){
283 if (!fMasked[channel] || !mask){
284 if (!isShort(channel) || use_small_sipms){
285 mean[s] += times[channel];
286 count[s] += 1;
287 }
288 }
289 }
290 }
291 }
292 if (count[0]>0 && count[1]>0) {
293 dT = (mean[0]/count[0] + mean[1]/count[1])/2.*ShipUnit::snd_TDC2ns - dL/2.; // TDC to ns = 6.25
294 }
295 return dT;
296}
297
298// ----- Public method Get position of impact point along the bar -----------------
299Float_t MuFilterHit::GetImpactXpos(Bool_t mask,Bool_t positive,Bool_t use_small_sipms,Bool_t isMC)
300{
301 if ( nSides!=2 ){
302 return -999.;
303 }
304 Float_t dT = GetDeltaT(mask,positive,use_small_sipms);
305 if (dT==-999.){
306 return -999.;
307 }
308
309 MuFilter* MuFilterDet = dynamic_cast<MuFilter*> (gROOT->GetListOfGlobals()->FindObject("MuFilter"));
310 Float_t bar_length = MuFilterDet->GetConfParF("MuFilter/UpstreamBarX");
311 Float_t signal_speed = MuFilterDet->GetConfParF("MuFilter/VandUpPropSpeed");
312 if (GetSystem()==3) {
313 signal_speed = MuFilterDet->GetConfParF("MuFilter/DsPropSpeed");
314 bar_length = MuFilterDet->GetConfParF("MuFilter/DownstreamBarX");
315 }
316 else if (GetSystem()==2) {
317 bar_length = MuFilterDet->GetConfParF("MuFilter/UpstreamBarX");
318 }
319 else {
320 bar_length = MuFilterDet->GetConfParF("MuFilter/VetoBarX");
321 }
322 double timeConversion = 1.;
323 if (!isMC) timeConversion = ShipUnit::snd_TDC2ns;
324 return 0.5*(bar_length + dT*timeConversion*signal_speed);
325}
326
327std::map<TString,Float_t> MuFilterHit::SumOfSignals(Bool_t mask)
328{
329/* use cases, for Veto and DS small/large ignored
330 sum of signals left large SiPM: LL
331 sum of signals right large SiPM: RL
332 sum of signals left small SiPM: LS
333 sum of signals right small SiPM: RS
334 sum of signals left and right:
335*/
336 Float_t theSumL = 0;
337 Float_t theSumR = 0;
338 Float_t theSumLS = 0;
339 Float_t theSumRS = 0;
340 for (unsigned int s=0; s<nSides; ++s){
341 for (unsigned int j=0; j<nSiPMs; ++j){
342 unsigned int channel = j+s*nSiPMs;
343 if (signals[channel]> 0){ // makes sense to sum up positive signals only
344 if (!fMasked[channel] || !mask){
345 if (s==0 and !isShort(j)){theSumL+= signals[channel];}
346 if (s==0 and isShort(j)){theSumLS+= signals[channel];}
347 if (s==1 and !isShort(j)){theSumR+= signals[channel];}
348 if (s==1 and isShort(j)){theSumRS+= signals[channel];}
349 }
350 }
351 }
352 }
353 std::map<TString,Float_t> sumSignals;
354 sumSignals["SumL"]=theSumL;
355 sumSignals["SumR"]=theSumR;
356 sumSignals["SumLS"]=theSumLS;
357 sumSignals["SumRS"]=theSumRS;
358 sumSignals["Sum"]=theSumL+theSumR;
359 sumSignals["SumS"]=theSumLS+theSumRS;
360 return sumSignals;
361}
362
363// ----- Public method Print -------------------------------------------
365{
366 std::cout << "-I- MuFilterHit: MuFilter hit " << " in detector " << fDetectorID;
367
368 if ( floor(fDetectorID/10000)==3&&fDetectorID%1000>59) {
369 std::cout << " with vertical bars"<<std::endl;
370 std::cout << "top digis:";
371 for (unsigned int j=0; j<nSiPMs; ++j){
372 std::cout << signals[j] <<" ";
373 }
374 }else{
375 std::cout << " with horizontal bars"<<std::endl;
376 for (unsigned int s=0; s<nSides; ++s){
377 if (s==0) {std::cout << "left digis:";}
378 else {std::cout << "right digis:";}
379 for (unsigned int j=0; j<nSiPMs; ++j){
380 std::cout << signals[j] <<" ";
381 }
382 }
383 }
384std::cout << std::endl;
385}
386// -------------------------------------------------------------------------
387
389
std::map< int, double > SiPM_qdc_calibration_constants
std::map< TString, Float_t > SumOfSignals(Bool_t mask=kTRUE)
Float_t GetImpactT(Bool_t mask=kTRUE, Bool_t positive=kTRUE, Bool_t use_small_sipms=kFALSE)
std::map< Int_t, Float_t > GetAllTimes(Bool_t mask=kTRUE, Bool_t positive=kTRUE, Bool_t use_small_sipms=kFALSE)
Float_t GetImpactXpos(Bool_t mask=kTRUE, Bool_t positive=kTRUE, Bool_t use_small_sipms=kFALSE, Bool_t isMC=kFALSE)
Float_t GetFastDeltaT(Bool_t mask=kTRUE, Bool_t positive=kTRUE, Bool_t use_small_sipms=kFALSE)
int GetPlane()
Definition MuFilterHit.h:43
virtual ~MuFilterHit()
Float_t fMasked[16]
Definition MuFilterHit.h:50
bool isShort(Int_t)
int GetSystem()
Definition MuFilterHit.h:42
bool isVertical()
Float_t flag
flag
Definition MuFilterHit.h:49
Float_t GetDeltaT(Bool_t mask=kTRUE, Bool_t positive=kTRUE, Bool_t use_small_sipms=kFALSE)
void Print() const
Float_t GetEnergy(Bool_t use_small_sipms=kFALSE)
std::map< Int_t, Float_t > GetAllSignals(Bool_t mask=kTRUE, Bool_t positive=kTRUE, Bool_t use_small_sipms=kFALSE, Bool_t use_calibration=kFALSE)
Int_t GetnSides(Int_t detID)
Definition MuFilter.cxx:715
void GetPosition(Int_t id, TVector3 &vLeft, TVector3 &vRight)
Definition MuFilter.cxx:639
Int_t GetnSiPMs(Int_t detID)
Definition MuFilter.cxx:708
Float_t GetConfParF(TString name)
Definition MuFilter.h:46
Int_t nSiPMs
Definition SndlhcHit.h:73
Float_t times[16]
SiPM signal.
Definition SndlhcHit.h:76
Int_t fDetectorID
Detector unique identifier.
Definition SndlhcHit.h:72
Int_t fDaqID[16]
SiPM time.
Definition SndlhcHit.h:77
Int_t nSides
number of SiPMs per side
Definition SndlhcHit.h:74
Float_t signals[16]
number of sides
Definition SndlhcHit.h:75
ClassImp(ecalContFact) ecalContFact