HYDRA_development_version
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
hmdcdigitizer.cc
Go to the documentation of this file.
1 #include "hgeantmdc.h"
2 #include "hgeantkine.h"
3 #include "hmdcdigitizer.h"
4 #include "hmdcdef.h"
5 #include "hdebug.h"
6 #include "hades.h"
7 #include "hmdcgeantcell.h"
8 #include "hmdccal1sim.h"
9 #include "hiterator.h"
10 #include "hruntimedb.h"
11 #include "hspectrometer.h"
12 #include "hmdcdetector.h"
13 #include "hevent.h"
14 #include "hcategory.h"
15 #include "hlocation.h"
16 #include "hmdclayergeompar.h"
17 #include "hmdcdigitpar.h"
18 #include "hmdccal2parsim.h"
19 #include "hmdccelleff.h"
20 #include "hmdcwirestat.h"
21 #include "hmessagemgr.h"
22 #include "hmdcsizescells.h"
23 #include "hmdcdedx2.h"
24 #include "hmdctimecut.h"
25 #include "hmdcgeomstruct.h"
26 
27 #include "TMath.h"
28 #include "TFile.h"
29 #include "TGraph.h"
30 
31 #include <iostream>
32 #include <iomanip>
33 #include <iomanip>
34 #include <map>
35 using namespace std;
36 
37 //*-- Author : A.Nekhaev
38 //*-- Modified: 17/01/2001 by Ilse Koenig
39 //*-- Modified: 05/11/2001 by J.Markert
40 //*-- Modified: 1/12/2000 by R. Holzmann
41 //*-- Modified: 30/07/99 by Ilse Koenig
42 //*-- Modified: 28/06/99 by Alexander Nekhaev
43 
44 //_HADES_CLASS_DESCRIPTION
45 ////////////////////////////////////////////////////////////////
46 //
47 // HMdcDigitizer digitizes data and puts output values into
48 // CAL1 category for simulated data
49 // OPTIONS:
50 //
51 // ----------------------- ------------
52 // | HMdcUnpacker | | HGeantMdc |
53 // | (embedding mode) | \ ------------
54 // | | \ ||
55 // ----------------------- \ || input to digitizer
56 // \ \/
57 // -------------- read real ------------------
58 // | HMdcCal1Sim | ------------> | HMdcDigitizer |
59 // -------------- <----------- | |
60 // write output | |
61 // ------------------
62 //
63 // HMdcDigitizer("","",option,flag)
64 //
65 // option=1 : TDC mode for two measured leading edges of two signals
66 // option=2 : TDC mode for measured leading and trailing edge of one signal
67 // flag=kTRUE : NTuple with internal variables of the digitizer will be filled and written
68 // to the outputfile digitizer.root inside the working directory
69 // flag=kFALSE: No NTuple is filled
70 //------------------------------------------------------------------------------------------------------
71 // setNTuple(kFALSE) no nTuple with internal data is filled and written out
72 // (kTRUE ) a NTuple with internal data is filled and written to digitizer.root
73 // setTdcMode(1) TDC mode for two measured leading edges of two signals
74 // (2) TDC mode for measured leading and trailing edge of one signal
75 // setOffsets(1.5,2.5,4.5,5.5, 0 or 1)sets offsets for each type of module which will be
76 // substracted from the calculated time1 and time2, the
77 // last flag switches the use of offsets on/off (1=on(default)).
78 // setEffLevel(90.,90.,90.,90., 0 or 1) sets level of cell efficiency cut for each type of module, the
79 // last flag switches the use of efficiency on/off (1=on(default)).
80 // setOffsets(1.5,2.5,4.5,5.5, 0 or 1) offsets (ns), which will be substracted from drif time + tof
81 // setTofUse(kFALSE) time of flight will not be added to drift times
82 // (kTRUE ) time of flight will be added to drift time
83 // setErrorUse(kTRUE) apply smearing of drift times with errors
84 // (kFALSE) do not apply smearing of drift times with errors
85 // setWireStatUse(kTRUE) take into account dead wires and efficiency of single wires
86 // (kFALSE) assume all wires working (default)
87 // setTimeCutUse(kTRUE) take into account time cuts
88 // (kFALSE) (default)
89 // setDeDxUse(kTRUE) calculate t2-t1 from energy loss of the particle (default)
90 // (kFALSE) calculate t2-t1 from GARFIELD tables
91 // setNoiseLevel(5.,5.,5.,5.) sets level of noise for each type of module
92 // setNoiseRange(low1,low2,low3,low4,hi1,hi2,hi3,hi4) sets the time window of the noise
93 // for each module type
94 // setNoiseBandWidth(width) (time-above threshold bump 0-width ns)
95 // setNoiseWhiteWidth(upperrange) (upper range in time-above threshold for white noise outside the bump)
96 // setNoiseWhiteRatio(ratio); (ratio between bump/white noise
97 // setNoiseMode(1)(default)GEANT cells will be overwritten by noise (if timenoise<time)
98 // (2) GEANT cells will not be touched
99 // setEmbeddingMode(Int_t) (default)1=realistic merging og REAL and GEANT data (default)
100 // 2=keep Geant data
101 // setSignalSpeed(0.004) sets the speed of the signal on the wire used to calulate the time offset
102 // by the signal propagation on the wire (ns/mm)
103 //------------------------------------------------------------------------------------------------------
104 // SHORT INTRODUCTION to HMdcDigitizer:
105 //
106 // SCHEME OF DIGITAZATION:
107 // 1. Reading input from HGeantMdc
108 // 2. Evaluation of fired cells
109 // 3. Calulation of drift times / wire offsets
110 // 4. Storing in HMdcGeantCell category (not persistent)
111 // 5. Filling arrays of all hits for one cell from HMdcGeantCell
112 // 6. set efficiency flags to the hits (cell efficiency/layer efficiency/dead wires/efficiency wires)
113 // 7. Filling real data into arrays if digitizer runs in embedding mode
114 // 8. sorting arrays with increasing arrival time of the signal (drift + error + tof + wireoffset)
115 // 9. selecting 1. and 2. valid hit in cell
116 // 10.filling output to HMdcCal1Sim
117 // 11.generation of noise
118 //
119 // INPUT DATA TO THE DIGITIZER:
120 // The Digitizer retrieves the GEANT data from
121 // HGeantMdc (sector,module,layer, hit: xcoord,ycoord,tof,ptot, incidence:theta,phi,tracknumber).
122 // Evaluation of fired cells:
123 // HMdcDigitizer::transform(Float_t xcoord, Float_t ycoord, Float_t theta,
124 // Float_t phi , Float_t tof , Int_t trkNum) calculates
125 // which cells have been hit by the track. The Information about the layer geometry
126 // (pitch, cathod distance, wire orientation, number of wires per layer and number of central wire)
127 // is taken from HMdcLayerGeomPar. Output of the calculation is the minimum distance from the wire
128 // and the impact angle in the coordinate system of the cell. All values are stored in the
129 // HMdcGeantCell for a maximum number of 15 hits per cell via
130 // HMdcDigitizer::storeCell(Float_t per, Float_t tof, Float_t myangle, Int_t trkNum,
131 // Bool_t flagCutEdge,Floa_t wireOffset).
132 //
133 // CALCULATION OF DRIFT TIMES:
134 // For each cell the drift time1 and time2 are calculated by corresponding functions of
135 // the HMdcCal2ParSim container which holds the calibration parameters for the "distance->drift time"
136 // calculation:
137 // HMdcCal2ParSim::calcTimeDigitizer (sector,module,angle,minDist,&time1,&time1Error) and
138 // HMdcCal2ParSim::calcTime2Digitizer(sector,module,angle,minDist,&time2,&time2Error).
139 // If setDeDxUse(kTRUE) (default) is chosen , the time to is calculated via
140 // HMdcDeDx2::scaledTimeAboveThreshold() inverse by the energy loss - Time over Threshold
141 // relation ship to assure compatible ToT/DeDx values for experimnt and simulation. The
142 // parameters for this transformation are obtained from experimental data.
143 //
144 // CALCULATION OF WIRE OFFSET:
145 // calcWireOffset(xcoor,ycoor,wOrient) calulates the time the signal of a given cell would take
146 // to popagate from the hit point to the readout electronis. The speed of the signal is taken from
147 // HMdcDigitPar::getSignalSpeed()(ns/mm). Internal functions of HMdcSizesCells are called to calulate
148 // the path length of the signal.
149 //
150 // EFFICIENCY CUTS:
151 // For each cell the efficiency cuts are calculated by a function of
152 // HMdcCellEff::calcEfficiency(module,minDist,angle,Level) which holds
153 // the information for the efficiency cuts on cell level. The level of the cuts can be specified
154 // by HMdcDigitizer::setEffLevel(90.,90.,90.,90.) per module. The cut is done on the basis of GARFIELD
155 // simulations which give information on the charge which is collected on the sense wire of
156 // each cell for all combinations of distance and impact angle. The numbers which have to be set
157 // are the percentage of maximum charge required to make a signal. Hits which are on the edge of
158 // the drift cell will not create a big amount of charge and therefore will be kicked out first.
159 // The second cut on the layer level is an overall layer efficiency (e.g. 0.98 for 98% Efficiency)
160 // and will reduce the overall number of fired cells. This value is taken from HMdcDigiPar container.
161 //
162 // SIMULATION OF DEAD WIRES:
163 // With setWireStatUse(kTRUE) the dead wires of the real data are correctly taken into account.
164 // This cut is handled in the same way as the effciency cuts and has the top priority
165 // (wire stat -> cell efficieny -> layer efficiency). In all cases the drift time will be set to -999.
166 // To get the correct result one has to analyze the status flags! The Information about the status
167 // of the wire is taken from HMdcWireStat.
168 //
169 // SIMULATION OD DELTA ELECTRONS
170 //
171 // void setDeltaElectronUse(Bool_t use, Bool_t useDeltaMomSel=kFALSE, Int_t ionId=109,Float_t t1min=-950.,Float_t t1max=400.,Float_t momCut=20.)
172 // void setDeltaElectronMinMomCut(Float_t s0=2.,Float_t s1=2.,Float_t s2=4.5,Float_t s3=2.,Float_t s4=2.,Float_t s5=4.5)
173 //
174 // Delta electrons can simulated by 3 different ways
175 //
176 // 1. Shooting electrons by kine generator ( primary electrons, momentun < momMaxDeltaElecCut) : useDeltaMomSel=kTRUE
177 // 2. Shooting beam ions by kine generator of evt file input (primary IonID)
178 // 3. Shooting delta electrons by evt file (primary electron, generator info -3) : useDeltaMomSel=kFALSE
179 //
180 // The delta electrons source are identified in the input by the methodes above.
181 // Than a random t0 is selected and applied to cal1 objects resluting from deltas.
182 // The time range used (default -950,400) can be selected. When using the timecut option
183 // all drift cells fired by deltas with negative t0 will leed to inefficiency of the MDC.
184 // To take care for the different material budgets of the RICH Mirror (2 sectors glass, 4 carbon)
185 // an additional low momentum cut (default 4.5 and 2. MeV) off per sector can be applied.
186 // By default the treatment of deltas is on and method 3 is set. If one wants to suppress
187 // delta electrons one can set setDeltaElectronMinMomCut() to high values.
188 //
189 // SELECTING 1. AND 2. VALID HIT:
190 // According to the the cuts a list of status flags for each recorded track is filled.
191 // After all calculations the list of Tracks is sorted by the arrival time (tof + drift time + wire offset) by
192 // HMdcDigitizer::select(Int_t nHits) because only the first track will create a signal.
193 // The first valid hit (status=1) inside the track list will be found by
194 // HMdcDigitizer::findFirstValidHit(Int_t* firsthit, Float_t* firsttime2, Int_t* endlist1)
195 // which returns the index number of the first valid hit and the the last hit which falls
196 // into the given time window defined by time2 of first valid hit.
197 // HMdcDigitizer::findSecondValidHit(Int_t endlist1,Int_t* secondhit)
198 // finds a second valid hit starting with the last entry of the list of the first valid hit.
199 // All variables will return -999 if no valid hits are found.
200 //
201 // FILLING OUTPUT:
202 // According to the two different TDC modes the HMdcCal1Sim category is filled.
203 // If HMdcDigitizer::setTofUse(kFALSE) is selected, the time of flight will be substracted and
204 // only the drift time is written to the output. With HMdcDigitizer::setOffsets(1.5,2.5,4.5,5.5, 0 or 1)
205 // a common minimum offset (fast particles) per module type can be set and will be subtracted
206 // from the calculated time to be closer to the real measurement situation.
207 // With setErrorUse(kFALSE) the digitizer can be forced to write the drift times without error smearing to the
208 // output.
209 //
210 // NOISE SIMULATION:
211 // Noise simulation should be used only in TDC mode 2 (leading + trailing edge)
212 // and not in embedding mode!
213 // The noise simulation is done after output data have been already filled to HMdcCal1 category.
214 // a loop over the category is performed and the noise is filled in 2 ways.
215 // 1. a loop over all existing cells in the setup of Mdc is done and randomly picked cells
216 // are filled width noise and added to the category ("only noise" cells).
217 // 2. For the existing cells filled with GEANT data a comparison between the randomly created noise
218 // time and the real time is done (if setNoiseMode(1)). The earlier of both is taken and if the noise wins
219 // the status flags are changed accordingly.
220 // With HMdcDigitizer::setNoiseLevel(5.,5.,5.,5.) the simulation of noise can be switched on.
221 // HMdcDigitizer::fillNoise() loops over all cells existing in the actual setup and will randomly
222 // pick cells according to the specified probability per module (5.==5%) and set the statusflag to 2.
223 // If a cell is selected for noise production a second random process generates the time in the
224 // range of the specified window set by HMdcDigitizer::setNoiseRange(low1,low2,low3,low4,hi1,hi2,hi3,hi4).
225 // The behaviour of the noise generation can be specified with
226 // 1. setNoiseBandWidth(width) (time-above threshold bump 0-width ns)
227 // 2. setNoiseWhiteWidth(upperrange) (upper range in time-above threshold for white noise outside the bump)
228 // 3. setNoiseWhiteRatio(ratio); (ratio between bump/white noise
229 // With HMdcDigitizer::setNoiseMode(1)(default) a given time in one of the original GEANT cells
230 // will be overwritten by the the noise time, if timenoise < time.In this case the statusflag of
231 // the cell will be set to 2 (valid hit but noise).In the case of HMdcDigitizer::setNoiseMode(2) the
232 // original GEANT cells will not be touched.
233 //
234 // EVENT EMBEDDING:
235 // In the embedding case of GEANT data into REAL data, the digitizer looks to the HMdcCal1Sim and gets the
236 // data words filled with the REAL data by the HMdcCalibrater1 which would fall in the same Cells as the
237 // GEANT data. If the embedding mode is set to 1 (default) the digitizer will do a "realistic" merging,
238 // that means, the first hit from REAL or GEANT data will be accepted. In embedding mode 2 the GEANT data
239 // will be allways kept and the coresponding REAL data will be overwritten by GEANT data. The embedding
240 // mode can be switched by HMdcDigitizer::setEmbeddingMode(Int_t)(1=realistic,2=keep Geant data).
241 // The status flag of REAL data will be 0, where as in the listStatus[5] the status flag will be 3 for
242 // REAL data hits which are merged into GEANT cells. The track number of real data HMdcCalSim objects will
243 // be the common track number which can be retrieved via gHades->getEmbeddingRealTrackId().
244 //
245 //
246 // SPECIAL FEATURES:
247 //-----------creating offsets to simulate calibrated offsets----------------------
248 // the impact of calibration of time offsets can be simulated too (by default this feature is not used).
249 // The offsets will be random generated from gRandom->Gaus(mean,sig).
250 // void setSigmaOffsets(Float_t sig) (default is 2ns)
251 // void setCreateOffsets(Bool_t kTRUE) (create new table of offsets)
252 // void initOffsets(TString filename) (if createoffsets=kTRUE a new table will be created and stored
253 // to file filename (if not "")
254 // if createoffsets=kFALSE and filename is provided the table
255 // will be read from ascii file)
256 //
257 //-----------manipulate drift times (tdc slope time errors...)--------------------------------
258 // void setScaleTime(Float_t scale) drift times will be scaled by scale (defualt 1.0)
259 // void setScalerTime1Err(Float_t m0=0,Float_t m1=0,Float_t m2=0,Float_t m3=0) (default 1.0)
260 // drift times errors (time1) will be scaled per module
261 //------------------------------------------------------------------------------------------------------
262 // MODE 1 (two times LEADING EDGE of the TDC signal)
263 // nHits == -2 for 2 valid hits
264 // == -1 for 1 valid hit
265 // == 0 for a not filled hit (e.g. 1 hit was kicked out by efficiency)
266 // status1 == 1 for a valid first hit
267 // == 2 for a valid first hit caused by noise
268 // == 3 for a valid first hit caused by real data embedding
269 // == -3 for a not valid hit
270 // == -5 for cutted by time cut
271 // == 0 no hit
272 // == 3 for REAL data (embedding)
273 // status2 == 1 for a valid second hit
274 // == 2 for a valid second hit caused by noise
275 // == 3 for a valid second hit caused by real data embedding
276 // == -3 for a not valid hit
277 // == -5 for cutted by time cut
278 // == 0 no hit
279 // == 3 for REAL data (embedding)
280 // angle1 == impact of track1 or -99 if not filled
281 // angle2 == impact of track2 or -99 if not filled
282 // minDist1== minimum distance of track1 or -99 if not filled
283 // minDist2== minimum distance of track2 or -99 if not filled
284 // error1 == error of time1
285 // error2 == error of time1 of the second valid hit or -99 if not filled
286 // tof1 == tof of time1
287 // tof2 == tof of time1 of the second valid hit or -999 if not filled
288 // wireOff1== signal time on wire of track1 or -99 if not filled
289 // wireOff2== signal time on wire of track2 or -99 if not filled
290 // nTrack1 == track number of the first valid hit
291 // == -99 if not filled
292 // nTrack2 == track number of the second valid hit
293 // == -99 if not filled
294 // time1 == drift time1 of the first valid hit
295 // == -999 if not filled
296 // time2 == drift time1 of the second valid hit
297 // == -999 if not filled
298 // listTrack[5] : contains the track number of the first 5 hits per cell
299 // == -99 if no hit was filled or noise
300 // listStatus[5]: contains the status flags of the first 5 hits per cell
301 // == -1 if hit was kicked out by cell efficiency cut
302 // == -2 if hit was kicked out by layer efficiency cut
303 // == -3 if hit was kicked out by wire stat
304 // == -4 if hit was kicked out by noise
305 // == -5 if cutted by time cut
306 // == 1 if hit is valid
307 // == 2 if hit is noise
308 // == 3 if hit is real data (embedding)
309 // == 0 if no hit was filled
310 // both lists will be filled even if no vaild hit was found
311 //
312 // MODE 2 (LEADING AND TRAILING EDGE of the TDC signal)
313 // nHits == +2 for 2 valid hits
314 // == 0 for not filled hit (e.g. 1 hit was kicked out by efficiency)
315 // status1 == 1 for a valid first hit
316 // == 2 for a valid first hit caused by noise
317 // == 3 for a valid first hit caused by real data embedding
318 // == -3 for a not valid hit
319 // == -5 for cutted by time cut
320 // == 0 or no hit
321 // == 3 REAL data (embedding)
322 // status2 == 1 for a valid first hit
323 // == 2 for a valid first hit caused by noise
324 // == 3 for a valid first hit caused by real data embedding
325 // == -3 for a not valid hit
326 // == -5 for cutted by time cut
327 // == no hit
328 // == 3 for REAL data (embedding)
329 // angle1 == impact of track1 or -99 if not filled
330 // angle2 == impact of track1 or -99 if not filled
331 // minDist1== minimum distance of track1 or -99 if not filled
332 // minDist2== minimum distance of track1 or -99 if not filled
333 // error1 == error of time1 or -99 if not filled
334 // error2 == error of time2 or -99 if not filled
335 // tof1 == tof of time1 or -999 if not filled
336 // tof2 == tof of time2 or -999 if not filled
337 // wireOff1== signal time on wire of track1 or -99 if not filled
338 // wireOff2== signal time on wire of track1 or -99 if not filled
339 // nTrack1 == track number of first valid hit
340 // == -99 if not filled
341 // nTrack2 == track number of first valid hit
342 // == -99 if not filled
343 // time1 == drift time1 of the first valid hit
344 // == -999 if not filled
345 // time2 == drift time2 of the first valid hit
346 // == -999 if not filled
347 // listTrack[5] : contains the track number of the first 5 hits per cell
348 // == -99 if no hit was filled or noise
349 // listStatus[5]: contains the status flags of the first 5 hits per cell
350 // == -1 if hit was kicked out by cell efficiency cut
351 // == -2 if hit was kicked out by layer efficiency cut
352 // == -3 if hit was kicked out by wire stat
353 // == -4 if hit was kicked out by noise
354 // == -5 if cutted by time cut
355 // == 1 if hit is valid
356 // == 2 if hit is noise
357 // == 3 if hit is real data (embedding)
358 // == 0 if no hit was filled
359 // both lists will be filled even if no vaild hit was found
360 //------------------------------------------------------------------------------------------------------
361 // EXAMPLES :
362 // In general: if nHits<0 ->TDC MODE=1
363 // if nHits>0 ->TDC MODE=2
364 // if status1/status2>0 -> valid hit (1: normal, 2: noise 3: real data (embedding))
365 // if status1/status2<0 -> no valid hit (-3)
366 //
367 // TDC MODE 1 (2 leading edges)
368 // no valid hit: status1=status2=-3 rest will be filled like normal hits
369 // 1 valid hit : time1!=-999,time2=-999,status1=1,status2=-3,nHits=-1,nTrack1!=-99,nTrack2=-99
370 // 2 valid hits: time1!=-999,time2!=-999,status1=status2=1,nHits=-2,nTrack1!=-99,nTrack2!=-99
371 // noise hit : if GEANT hit was overwritten:status1/status2 =2 rest filled like normal hits
372 // if a noise cell was added to GEANT cells:
373 // time1!=-999,time2=-999,status1=2,status2=-3,nHits=-1,
374 // nTrack1=nTrack2=-99
375 //
376 // TDC MODE 2 (leading and trailing edge)
377 // no valid hit: status1=status2=-3 rest will be filled like normal hit
378 // 1 valid hit : time1!=-999,time2!=-999,status1=status2=1,nHits=2,nTrack1=nTrack2!=-99
379 // noise hit : if GEANT hit was overwritten:status1=status2=2 rest filled like normal hits
380 // if a noise cell was added to GEANT cells:
381 // time1!=-999,time2!=-999,status1=status2=2,nHits=2,
382 // nTrack1=nTrack2=-99
383 //
384 // MODE1 and MODE2 :
385 //
386 // if status1/status2=-3 looking to the StatusList[5]: -1 cut on Cell efficiency
387 // -2 cut on Layer efficiency
388 // The TrackList[5] will be filled with the GEANT track numbers no matter if the hit was
389 // valid or not or overwritten by noise!
390 /////////////////////////////////////////////////////////////////
391 
392 Float_t HMdcDigitizer::dTime [NMAXHITS] = {0.};
393 Float_t HMdcDigitizer::dTime2[NMAXHITS] = {0.};
394 Float_t HMdcDigitizer::dTimeErr [NMAXHITS] = {0.};
395 Float_t HMdcDigitizer::dTime2Err[NMAXHITS] = {0.};
396 Float_t HMdcDigitizer::minimumdist[NMAXHITS] = {0.};
397 Int_t HMdcDigitizer::track[NMAXHITS] = {-99};
398 Float_t HMdcDigitizer::timeOfFlight[NMAXHITS] = {0.};
399 Float_t HMdcDigitizer::angle[NMAXHITS] = {0.};
402 Bool_t HMdcDigitizer::cutEdge[NMAXHITS] = {kFALSE};
403 Float_t HMdcDigitizer::wireOffset[NMAXHITS] = {0.};
404 Float_t HMdcDigitizer::efficiency[NMAXHITS] = {0.};
405 Float_t HMdcDigitizer::theta[NMAXHITS] = {0.};
406 
407 
409 {
410  initVariables();
411 }
412 HMdcDigitizer::HMdcDigitizer(const Text_t *name,const Text_t *title):
413 HReconstructor(name,title)
414 {
415  initVariables();
416 }
417 
418 HMdcDigitizer::HMdcDigitizer(const Text_t *name,const Text_t *title,Int_t TDCMODE,Bool_t NTUPLE) :
419 HReconstructor(name,title)
420 {
421  // TDCMODE sets the simulation mode to the two different
422  // possibilities of the TDC: 1 == to leading edges
423  // 2 == leading and trailing edge
424  // NTUPLE switches the NTuple with the internal information of
425  // the digitizer ON or OFF: kFALSE == no NTuple filled
426  // kTRUE == NTuple filled.
427 
428  initVariables();
429  setTdcMode(TDCMODE);
430  setNTuple(NTUPLE);
431 }
432 
434 
435 
436  if(iterin) delete iterin;
437  if(itercell) delete itercell;
438  if(itercal1) delete itercal1;
439 }
440 
441 void HMdcDigitizer::setOffsets(Float_t off0,Float_t off1,Float_t off2,Float_t off3,Int_t on_off)
442 {
443  // set global time offsets per drift chamber type in nano seconds.
444  // The offsets will be substracted from the drift times if on_off == 1
445  //
446  if(on_off == 1)
447  {
448  useOffsets = kTRUE;
449  }
450  else
451  {
452  useOffsets = kFALSE;
453  }
454  offsets[0] = off0;
455  offsets[1] = off1;
456  offsets[2] = off2;
457  offsets[3] = off3;
458 }
459 void HMdcDigitizer::setEffLevel(Float_t eff0,Float_t eff1,Float_t eff2,Float_t eff3,Int_t on_off)
460 {
461  // set Cell efficiency level per drift chamber type.
462  // settings will be used if on_off == 1.
463  if(on_off == 1)
464  {
465  useCellEff = kTRUE;
466  }
467  else
468  {
469  useCellEff = kFALSE;
470  }
471  effLevel[0] = eff0;
472  effLevel[1] = eff1;
473  effLevel[2] = eff2;
474  effLevel[3] = eff3;
475 }
476 
477 void HMdcDigitizer::setNoiseLevel(Float_t noise0,Float_t noise1,Float_t noise2,Float_t noise3,Int_t on_off)
478 {
479  // set the noise level per drift chambers in per cent.
480  // noise simulation will be used if on_off == 1
481 
482  if(on_off == 1)
483  {
484  useNoise = kTRUE;
485  }
486  else
487  {
488  useNoise = kFALSE;
489  }
490  noiseLevel[0] = noise0 * 0.01;
491  noiseLevel[1] = noise1 * 0.01;
492  noiseLevel[2] = noise2 * 0.01;
493  noiseLevel[3] = noise3 * 0.01;
494 }
495 
496 void HMdcDigitizer::setNoiseRange(Int_t rangeLo0,Int_t rangeLo1,Int_t rangeLo2,Int_t rangeLo3,
497  Int_t rangeHi0,Int_t rangeHi1,Int_t rangeHi2,Int_t rangeHi3)
498 {
499  // set the noise range in time1 in nano seconds per chamber type.
500  noiseRangeLo[0] = rangeLo0;
501  noiseRangeLo[1] = rangeLo1;
502  noiseRangeLo[2] = rangeLo2;
503  noiseRangeLo[3] = rangeLo3;
504  noiseRangeHi[0] = rangeHi0;
505  noiseRangeHi[1] = rangeHi1;
506  noiseRangeHi[2] = rangeHi2;
507  noiseRangeHi[3] = rangeHi3;
508 }
509 
510 void HMdcDigitizer::setScalerTime1Err(Float_t m0,Float_t m1,Float_t m2,Float_t m3)
511 {
512  // set the scaler values for error of time1 per chamber type.
513  scaleError[0] = m0;
514  scaleError[1] = m1;
515  scaleError[2] = m2;
516  scaleError[3] = m3;
517 }
518 
519 
520 
522 {
523  // sets all used variables to the initial values
524  fbetadEdx = HMdcDeDx2::energyLossGraph(14,0.6,"beta");
525  fBetaLow = 0.7;
526  useDeDxScaling= kTRUE;
527  useDeDxTimeScaling = kTRUE;
528  fGeantCellCat = 0;
529  fCalCat = 0;
530  fDigitGeomPar = 0;
531  fDigitPar = 0;
532  fCal2ParSim = 0;
533  fCellEff = 0;
534  fWireStat = 0;
535  fTimeCut = 0;
536  fsizescells = 0;
537  fdEdX = 0;
538  fCal = 0;
539  fCalnoise = 0;
540  fCell = 0;
541  iterin = 0;
542  itercell = 0;
543  itercal1 = 0;
544  fEventId = 0;
545  pi = acos(-1.)/180;
546  time1 = 0;
547  time1Error = 0;
548  time2 = 0;
549  time2Error = 0;
550  setTdcMode(2);
551  setEffLevel (90 ,90 ,90 ,90);
552  setNoiseLevel(5. ,5. ,5. ,5.);
553  setOffsets (1.5,2.5,4.5,5.5);
554  setOffsetsUse (kFALSE);
555  setCellEffUse (kTRUE);
556  setWireStatUse (kFALSE);
557  setWireStatEffUse(kTRUE);
559  setWireStatOffsetUse(kTRUE);
560  setNoiseUse (kFALSE);
561  setTofUse (kTRUE);
562  setErrorUse (kTRUE);
563  setWireOffsetUse(kTRUE);
564  setDeDxUse (kTRUE);
565  setTimeCutUse (kFALSE);
566  setNTuple (kFALSE);
567  hasPrinted = kFALSE;
568  setTime1Noise(0.);
569  setTime2Noise(0.);
571  setNoiseMode(1);
572  for(Int_t i = 0; i < 5; i ++)
573  {
574  arrayNoise[i] = 0;
575  }
576  setNoiseRange(-500,-500,-500,-500,
577  1500,1500,1500,1500);
578  setNoiseBandWidth(20.);
579  setNoiseWhiteWidth(500.);
580  setNoiseWhiteRatio(0.1);
581  setEmbeddingMode(1);
582  setSignalSpeed(0.004);// ns/mm
583  for(Int_t i = 0; i < 4; i ++)
584  {
585  scaleError[i] = 1.;
586  scaleErrorMIPS[i] = 1.;
587  }
588 
589  for(Int_t s = 0; s < 6; s ++){
590  for(Int_t m = 0; m < 4; m ++){
591  for(Int_t l = 0; l < 6; l ++){
592  for(Int_t c = 0; c < 220; c ++){
593  rndmoffsets[s][m][l][c] = 0.0;
594  }
595  }
596  }
597  }
598  setCreateOffsets(kFALSE);
599  offsetsCreated = kFALSE;
600  setSigmaOffsets(2.0);
601  setScaleTime(1.0);
602  vLayEff.reserve(500);
603  setDeltaElectronUse(kTRUE,kFALSE,109,-950.,400.,20.,2.);
604  setDeltaElectronMinMomCut(2.,2.,4.5,2.,2.,4.5);
605 }
607  // Get pointers to the needed containers.The containers are
608  // created and added to the runtime Database if the are not existing
609 
610  fDigitGeomPar = (HMdcLayerGeomPar*)(((HRuntimeDb*)(gHades->getRuntimeDb()))->getContainer("MdcLayerGeomPar"));
611  if(!fDigitGeomPar)
612  {
613  Error("HMdcDigitizer:init()","ZERO POINTER FOR HMDCLAYERGEOMPAR RECIEVED!");
614  exit(1);
615  }
616  fDigitPar = (HMdcDigitPar*)(((HRuntimeDb*)(gHades->getRuntimeDb()))->getContainer("MdcDigitPar"));
617  if(!fDigitPar)
618  {
619  Error("HMdcDigitizer:init()","ZERO POINTER FOR HMDCDIGITPAR RECIEVED!");
620  exit(1);
621  }
622  fCal2ParSim = (HMdcCal2ParSim*)(((HRuntimeDb*)(gHades->getRuntimeDb()))->getContainer("MdcCal2ParSim"));
623  if(!fCal2ParSim)
624  {
625  Error("HMdcDigitizer:init()","ZERO POINTER FOR HMDCCAL2PARSIM RECIEVED!");
626  exit(1);
627  }
628  geomstruct = (HMdcGeomStruct*)(((HRuntimeDb*)(gHades->getRuntimeDb()))->getContainer("MdcGeomStruct"));
629  if(!geomstruct)
630  {
631  Error("HMdcDigitizer:init()","ZERO POINTER FOR HMDCGEOMSTRUCT RECIEVED!");
632  exit(1);
633  }
634  if(getCellEffUse())
635  {
636  fCellEff = (HMdcCellEff*)(((HRuntimeDb*)(gHades->getRuntimeDb()))->getContainer("MdcCellEff"));
637  if(!fCellEff)
638  {
639  Error("HMdcDigitizer:init()","ZERO POINTER FOR HMDCCELLEFF RECIEVED!");
640  exit(1);
641  }
642  }
643  if(getWireStatUse())
644  {
645  fWireStat = (HMdcWireStat*)(((HRuntimeDb*)(gHades->getRuntimeDb()))->getContainer("MdcWireStat"));
646  if(!fWireStat)
647  {
648  Error("HMdcDigitizer:init()","ZERO POINTER FOR HMDCWIRESTAT RECIEVED!");
649  exit(1);
650  }
651 
652  }
653 
655  if(!fsizescells)
656  {
657  Error("HMdcDigitizer:init()","ZERO POINTER FOR HMDCSIZESCELLS RECIEVED!");
658  exit(1);
659  }
660 
661  if(getDeDxUse())
662  {
663  fdEdX = (HMdcDeDx2*)(((HRuntimeDb*)(gHades->getRuntimeDb()))->getContainer("MdcDeDx2"));
664  if(!fdEdX)
665  {
666  Error("HMdcDigitizer:init()","ZERO POINTER FOR HMDCDEDX2 RECIEVED!");
667  exit(1);
668  }
669  }
670  if(getTimeCutUse() )
671  {
672  fTimeCut = (HMdcTimeCut*) gHades->getRuntimeDb()->getContainer("MdcTimeCut");
673  }
674 
675 }
676 
678  // Creates an NTuple for the internal infomation of the digitizer
679  // which is stored in the file digitizer.root in the working directory.
680  // The NTuple contains
681  // sec,mod,lay,cell: the "software address" of a single cell
682  // dist,angle: minimum distance of the track to the wire
683  // and impact angle in coordinates of the cell
684  // time1, time1Err,time2,time2Err: values for the drift times
685  // tof: time of flight
686  // cutEdge: 0 if minimum distance smaler than cell bounderies, 1 if larger
687  // status: 1 if valid hit, 2 if noise, 3 for REAL data
688  // -1 if cut by cell efficiency
689  // -2 if cut by layer efficiency
690  // track: track number (-99 if no real track)
691  // eff: efficiency value which would correspond to a cut on this minimum dist
692 
693  myoutput->cd();
694  distance_time = new TNtuple("cal2sim", "cal2sim", "sec:mod:lay:cell:dist:angle:time1:time1Err:time2:time2Err:tof:cutEdge:status:track:eff");
695 
696 }
697 
698 Bool_t HMdcDigitizer::init(void) {
699  // The parameter containers and the iterators over
700  // the categorys MdcGeanRaw, MdcGeantCell and MdcCal1Sim are created.
701  // The actual setup of the Mdc detector in the running analysis
702  // is retrieved.
704  getMdcSetup();
705 
706  fGeantMdcCat = (HCategory*)(((HEvent*)(gHades->getCurrentEvent()))->getCategory(catMdcGeantRaw));
707  if(!fGeantMdcCat) {
708  Error("HMdcDigitizer::init()","HGeant MDC input missing");
709  return kFALSE;
710  }
711  iterin = (HIterator*)((HCategory*)fGeantMdcCat)->MakeIterator("native");
712 
713  fGeantKineCat = (HCategory*)(((HEvent*)(gHades->getCurrentEvent()))->getCategory(catGeantKine));
714  if(!fGeantKineCat) {
715  Error("HMdcDigitizer::init()","HGeant Kine input missing");
716  return kFALSE;
717  }
718 
719  fGeantCellCat = (HCategory*)(((HEvent*)(gHades->getCurrentEvent()))->getCategory(catMdcGeantCell));
720  if (!fGeantCellCat) {
721  fGeantCellCat = (HCategory*)((HMdcDetector*)(((HSpectrometer*)(gHades->getSetup()))->getDetector("Mdc"))->buildCategory(catMdcGeantCell));
722  if (!fGeantCellCat) return kFALSE;
723  else ((HEvent*)(gHades->getCurrentEvent()))->addCategory(catMdcGeantCell,fGeantCellCat,"Mdc");
724  }
725  fGeantCellCat->setPersistency(kFALSE); // We don't want to write this one
726  itercell = (HIterator*)((HCategory*)fGeantCellCat)->MakeIterator("native");
727 
728  fCalCat = (HCategory*)(((HEvent*)(gHades->getCurrentEvent()))->getCategory(catMdcCal1));
729  if (!fCalCat) {
730  HMdcDetector* mdc = (HMdcDetector*)(((HSpectrometer*)(gHades->getSetup()))->getDetector("Mdc"));
731  fCalCat = (HCategory*)(((HMdcDetector*)mdc)->buildMatrixCategory("HMdcCal1Sim",0.5F));
732  if (!fCalCat) return kFALSE;
733  else ((HEvent*)(gHades->getCurrentEvent()))->addCategory(catMdcCal1,fCalCat,"Mdc");
734  itercal1 = (HIterator*)fCalCat->MakeIterator("native");
735 
736  } else {
737  itercal1 = (HIterator*)fCalCat->MakeIterator("native");
738  if (fCalCat->getClass() != HMdcCal1Sim::Class()) {
739  Error("HMdcDigitizer::init()","Misconfigured output category");
740  return kFALSE;
741  }
742  }
743  if(getNTuple())
744  {
745  // create output file and NTuple
746  myoutput = new TFile("digitizer.root","RECREATE");
747  myoutput->cd();
748  setNTuples();
749  }
750 
751  return kTRUE;
752 }
754 {
755  // setup some local variables which need already initialized
756  // parameter containers.
758  memset(&rndmoffsets[0][0][0][0],0, sizeof(Float_t) * 6 * 4 * 6 * 220);
759 
760  for(Int_t s = 0;s < 6; s ++){
761  for(Int_t m = 0; m < 4; m ++){
762  for(Int_t l = 0; l < 6; l ++){
763  for(Int_t c = 0; c < 220; c ++){
764  rndmoffsets[s][m][l][c] = fWireStat->getOffset(s,m,l,c);
765  }
766  }
767  }
768  }
769 
770  } else {
771  if(!offsetsCreated) memset(&rndmoffsets[0][0][0][0],0, sizeof(Float_t) * 6 * 4 * 6 * 220);
772  }
773 
775 
776  for(Int_t m = 0; m < 4; m ++){
779  }
780 
781 
782  Bool_t result = kFALSE;
783 
785 
786  result = fsizescells->initContainer();
787  if(result){
788  // init layEff vars
789  for(Int_t s = 0;s < 6; s ++){
790  for(Int_t m = 0; m < 4; m ++){
791  for(Int_t l = 0; l < 6; l ++){
792  layEff.cmin[s][m][l] =-1;
793  layEff.cmax[s][m][l] =-1;
794  layEff.Lmax[s][m][l] =-1;
795  layEff.Lmin[s][m][l] =-1;
796 
797  }
798  }
799  }
800 
801  const HGeomVector& p4 = fsizescells->getTargetMiddlePoint(); // use target mid point for impact angle calculation (min + max vals only)
802 
803  for(Int_t s = 0;s < 6; s ++){
804  for(Int_t m = 0; m < 4; m ++){
805  if(!fsizescells->modStatus(s,m)) continue;
806  for(Int_t l = 0; l < 6; l ++){
807 
808  layEff.cmax[s][m][l] = (*fsizescells) [s][m][l].getNCells()-1;
809  layEff.cmin[s][m][l] = (*fDigitGeomPar)[s][m][l].getCentralWireNr(); // round to int
810 
811  Int_t c = layEff.cmax[s][m][l];
812  {
813  const HGeomVector& p1 = *(*fsizescells)[s][m][l][c].getWirePoint(0);
814  const HGeomVector& p2 = *(*fsizescells)[s][m][l][c].getWirePoint(1);
815  HGeomVector tmp = p2+p1;
816  tmp*=0.5;
817  HGeomVector p3 = tmp; // mid of wire
818  HMdcSizesCellsLayer &sizesCellsLayer = (*fsizescells)[s][m][l];
819  Int_t firstCell,lastCell;
820  Float_t firstCellPath,midCellPath,lastCellPath;
821  Int_t ncells=0;
822  if(sizesCellsLayer.calcCrossedCells(p4.getX(),p4.getY(),p4.getZ(),
823  p3.getX(),p3.getY(),p3.getZ(),
824  firstCell,lastCell,
825  firstCellPath,midCellPath,lastCellPath))
826  {
827 
828  ncells = 1;
829  ncells += lastCell-firstCell;
830 
831  Float_t totalePathInLayer = 0.;
832  for(Int_t cell=firstCell;cell<=lastCell;++cell) {
833  Float_t cellPath;
834  if (cell == firstCell) { cellPath = firstCellPath;}
835  else if (cell == lastCell) { cellPath = lastCellPath; }
836  else { cellPath = midCellPath; }
837  totalePathInLayer += cellPath;
838  }
839  layEff.Lmax[s][m][l] = totalePathInLayer ;
840  }
841  }
842  c = layEff.cmin[s][m][l];
843  {
844  const HGeomVector& p1 = *(*fsizescells)[s][m][l][c].getWirePoint(0);
845  const HGeomVector& p2 = *(*fsizescells)[s][m][l][c].getWirePoint(1);
846  HGeomVector tmp = p2+p1;
847  tmp*=0.5;
848  HGeomVector p3 = tmp; // mid of wire
849  HMdcSizesCellsLayer &sizesCellsLayer = (*fsizescells)[s][m][l];
850  Int_t firstCell,lastCell;
851  Float_t firstCellPath,midCellPath,lastCellPath;
852  Int_t ncells=0;
853  if(sizesCellsLayer.calcCrossedCells(p4.getX(),p4.getY(),p4.getZ(),
854  p3.getX(),p3.getY(),p3.getZ(),
855  firstCell,lastCell,
856  firstCellPath,midCellPath,lastCellPath))
857  {
858 
859  ncells = 1;
860  ncells += lastCell-firstCell;
861 
862  Float_t totalePathInLayer = 0.;
863  for(Int_t cell=firstCell;cell<=lastCell;++cell) {
864  Float_t cellPath;
865  if (cell == firstCell) { cellPath = firstCellPath;}
866  else if (cell == lastCell) { cellPath = lastCellPath; }
867  else { cellPath = midCellPath; }
868  totalePathInLayer += cellPath;
869  }
870  layEff.Lmin[s][m][l] = totalePathInLayer ;
871  }
872  }
873  } // end lay loop
874  } // end mod loop
875  } // end sec loop
876 
877  }
878 
879  printStatus();
880  return result;
881 }
883 {
884  // Prints the Options, default settings and
885  // actual configuration of HMdcDigitizer.
886 
887  SEPERATOR_msg("*",60);
888  INFO_msg(10,HMessageMgr::DET_MDC,"DEFAULT SETTINGS");
889  SEPERATOR_msg("-",60);
890  INFO_msg(10,HMessageMgr::DET_MDC,"Options input 1 (default) two leading edges");
891  INFO_msg(10,HMessageMgr::DET_MDC," 2 leading and trailing edge");
892  INFO_msg(10,HMessageMgr::DET_MDC,"NTuple kFALSE (default) no NTuple filled");
893  INFO_msg(10,HMessageMgr::DET_MDC," kTRUE NTuple in digitizer.root filled");
894  INFO_msg(10,HMessageMgr::DET_MDC,"Use Offsets kFALSE (default)");
895  INFO_msg(10,HMessageMgr::DET_MDC,"Use Tof kTRUE (default) cal1sim = drift time + tof");
896  INFO_msg(10,HMessageMgr::DET_MDC,"Use Cell Eff kFALSE (default)");
897  INFO_msg(10,HMessageMgr::DET_MDC,"Use Noise kFALSE (default)");
898  INFO_msg(10,HMessageMgr::DET_MDC,"Noise mode 1 (default) GEANT hits will be replaced by noise");
899  SEPERATOR_msg("-",60);
900  INFO_msg(10,HMessageMgr::DET_MDC,"ACTUAL CONFIGURATION");
901 
902  SEPERATOR_msg("*",60);
903  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName(),"HMdcDigiSetup:");
904  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
905  ,"tdcModeDigi = %i : 1 = two leading edges, 2 = leading and trailing edge",getTdcMode());
906  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
907  ,"NtupleDigi = %i : 0 = noNtuple, 1 = digitizer.root",(Int_t)getNTuple());
908  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
909  ,"useTofDigi = %i : 0 = NoTof in cal1, 1 = Tof in cal1 \n",(Int_t)getTofUse());
910  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
911  ,"useErrorDigi = %i : 0 = NoErr in cal1, 1 = Err in cal1 \n",(Int_t)getErrorUse());
912  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
913  ,"useWireOffsetDigi = %i : 1 = add wireOffset to drift time, 0 = don't add wireOffsets"
914  , getWireOffsetUse());
915  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
916  ,"useWireStatDigi = %i : 1 = use wirestat container, 0 = don't use wirestat container"
917  , getWireStatUse());
918  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
919  ,"useWireStatEff = %i : 1 = use eff from wirestat container"
920  , getWireStatEffUse());
921  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
922  ,"useWireStatOffset = %i : 1 = use offsets from wirestat container"
924  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
925  ,"useTimeCut = %i : 1 = use time cut container, 0 = don't use time cut container"
926  , (Int_t)getTimeCutUse());
927  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
928  ,"offsetsOnDigi = %i : 0 = global offsets off, 1 = global offsets on",(Int_t)getOffsetsUse());
929  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
930  ,"offsetsDigi = %4.1f %4.1f %4.1f %4.1f ns offset per plane (substracted from (drift time + tof))\n"
931  ,getOffset(0),getOffset(1),getOffset(2),getOffset(3));
932  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
933  ,"noiseModeDigi = %i : 1 = override geant by noise, 2 = keep geant cells",getNoiseMode());
934  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
935  ,"noiseOnDigi = %i : 0 = noise off, 1 = noise on",(Int_t)getNoiseUse());
936  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
937  ,"noiseLevelDigi = %4.1f%% %4.1f%% %4.1f%% %4.1f%% noise level per plane"
938  ,100*getNoiseLevel(0),100*getNoiseLevel(1),100*getNoiseLevel(2),100*getNoiseLevel(3));
939  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
940  ,"noiseRangeDigi =%5i %5i %5i %5i %5i %5i %5i %5i ns lower/upper limit of noise"
943  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
944  ,"noiseBandWidth = %5.1f ns : width of the t2-t1 noise band",getNoiseBandWidth());
945  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
946  ,"noiseWhiteWidth = %5.1f ns : width of the t2-t1 white noise region",getNoiseWhiteWidth());
947  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
948  ,"noiseWhiteRatio = %5.1f : ratio between t2-t1 band/white noise\n",getNoiseWhiteRatio());
949  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
950  ,"cellEffOnDigi = %i : 0 = cellEff off, 1 = cellEff",(Int_t)getCellEffUse());
951  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
952  ,"cellEffDigi = %4.1f%% %4.1f%% %4.1f%% %4.1f%% level of cellEff per plane"
954  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
955  ,"fBetaLow = %f : onset scaling point for LayerEff,CellEff,time1Err with dEdx"
956  , fBetaLow);
957  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
958  ,"scaleTime1Err = %5.4f %5.4f %5.4f %5.4f input scaling for t1 err"
960  gHades->getMsg()->info(10,HMessageMgr::DET_MDC,GetName()
961  ,"scaleTime1ErrMIPS = %5.4f %5.4f %5.4f %5.4f scaling for t1 err for MIPS"
963  hasPrinted=kTRUE;
964 }
965 
967 {
968  // If NTuple exist it will be written to digitizer.root.
969 
970  if(getNTuple())
971  {
972  // The NTuple is written to the output file
973  myoutput->cd();
974  distance_time->Write();
975  myoutput->Save();
976  myoutput->Close();
977  }
978  return kTRUE;
979 }
980 
982  // GEANT data are retrieved from HGeantMdc.
983  // The GEANT hits will be transformed to the
984  // layer coordinate system of the Mdc to find
985  // the fired cells. For the fired cells the drift time
986  // calulation, noise generation and efficiency cuts will
987  // be performed according to the settings and the results
988  // will be stored in HMdcCal1Sim.
989  Float_t xcoord, ycoord, tof, theta, phi, ptot;
990  Int_t trkNum;
991  myalpha = 0;
992  HGeantMdc* fGeant;
993  loc.set(4,0,0,0,0); // location used to fill the HMdcGeantCell category
994 
995  vLayEff.clear();
996 
997  //---------------------------------------------------------------------
998  // In embedding mode the trackNumber of the
999  // real data has to be set
1000  if(getEmbeddingMode() > 0)
1001  {
1002  if(gHades->getEmbeddingDebug() == 1) fCalCat->Clear();
1003 
1004  itercal1->Reset();
1005  while ((fCal = (HMdcCal1Sim *)itercal1->Next()) != NULL)
1006  {
1007 
1010  fCal->setStatus1(3);
1011  fCal->setStatus2(3);
1012  fCal->resetTrackList(-99); // no track list
1013  fCal->setTrackList(0,gHades->getEmbeddingRealTrackId()); // real data
1014  fCal->resetStatusList(0); // status flag reset
1015  fCal->setStatusList(0,3); // real data
1016  }
1017  }
1018  //---------------------------------------------------------------------
1019 
1020  //---------------------------------------------------------------------
1021  // time shift for delta electrons
1022  if(useDeltaElectrons)
1023  {
1024  mDeltaTrackT0.clear();
1025 
1026  if(fGeantKineCat){
1027  Int_t nKine = fGeantKineCat->getEntries();
1028  for(Int_t i=0;i<nKine;i++){
1029  HGeantKine* kine = (HGeantKine*)fGeantKineCat-> getObject(i);
1030  Float_t mom = kine->getTotalMomentum() ;
1031  Int_t generator = kine->getGeneratorInfo();
1032  if(kine->getParentTrack() == 0 &&
1033  (kine->getID() == ionID || // beam ions simulated
1034  ( useDeltaMomSelection && kine->getID() == 3 && mom < momMaxDeltaElecCut) || // any electron < momCut (shooting with kine generator)
1035  (!useDeltaMomSelection && kine->getID() == 3 && generator ==-3 ) // delta electrons input file source id ==-3
1036  )
1037  )
1038  {
1039  Float_t t0offset = gRandom->Rndm()* (t1maxDeltaElec-t1minDeltaElec) + t1minDeltaElec;
1040  mDeltaTrackT0[kine] = t0offset;
1041  }
1042  }
1043  }
1044  }
1045  //---------------------------------------------------------------------
1046  iterin->Reset();
1047  while((fGeant = (HGeantMdc*)iterin->Next()) != NULL) {// loop over HGeant input
1048  loc[0] = (Int_t)(fGeant->getSector());
1049  loc[1] = (Int_t)(fGeant->getModule());
1050 
1051  if(!testMdcSetup(loc[0],loc[1]) ) continue; // checks if the module is present in the setup
1052 
1053  loc[2] = (Int_t)(fGeant->getLayer());
1054  // loc[3] is filled in transform(...) with the cell number
1055  fGeant->getHit(xcoord, ycoord, tof, ptot);
1056  fGeant->getIncidence(theta, phi);
1057  trkNum = fGeant->getTrack();
1058 
1059  //---------------------------------------------------------------------
1060  // identify delta electrons
1061  Bool_t isDelta = kFALSE;
1062  Float_t mom = 0;
1063  Int_t generator = 0;
1064 
1065  HGeantKine* primary = HGeantKine::getPrimary(trkNum,(HLinearCategory*)fGeantKineCat);
1066  if(primary) { // primary
1067  mom = primary->getTotalMomentum() ;
1068  generator = primary->getGeneratorInfo();
1069  if( primary->getID() == ionID || // beam ions simulated
1070  ( useDeltaMomSelection && primary->getID() == 3 && mom <momMaxDeltaElecCut) || // any electron < momCut (shooting with kine generator)
1071  (!useDeltaMomSelection && primary->getID() == 3 && generator ==-3 ) // delta electrons input file source id ==-3
1072  ) isDelta = kTRUE;
1073  } else {
1074  Error("execute()","No primary for trk = %i found!",trkNum);
1075  }
1076  //---------------------------------------------------------------------
1077 
1078  //---------------------------------------------------------------------
1079  // time shift for delta electrons
1080  if(useDeltaElectrons)
1081  {
1082  if(isDelta)
1083  {
1084  Float_t t0offset = 0;
1085  itDelta = mDeltaTrackT0.find(primary);
1086  if(itDelta != mDeltaTrackT0.end()) t0offset = itDelta->second;
1087  else {
1088  Error("execute()","No primary in delta map for trk = %i found! Should not happen!",trkNum);
1089  primary->print();
1090  }
1091  if(mom < momMinDeltaCut[loc[0]]) continue;
1092  if(fProbDeltaAccepted<1){
1093  if(gRandom->Rndm() < fProbDeltaAccepted) continue; // adjust yield of delta electrons
1094  }
1095  tof+=t0offset;
1096  fGeant->setHit(xcoord, ycoord, tof, ptot); // change also TOF in of geant object to allow matching by tof with cal1 in tracking later
1097  }
1098  } else { // skipp all deltaelectrons
1099  if(isDelta) continue;
1100  }
1101  //---------------------------------------------------------------------
1102 
1103  if(loc[2]<6)
1104  {
1105 
1106  Int_t ind = findTrack(trkNum);
1107  if(ind == -1) { // generate random numbers for layer eff
1108  HMdcDigiLayEff layeff(trkNum);
1109  layeff.ct[loc[0]][loc[1]][loc[2]]++;
1110  vLayEff.push_back(layeff);
1111  } else {
1112  vLayEff[ind].ct[(Int_t)loc[0]][(Int_t)loc[1]][(Int_t)loc[2]]++;
1113  }
1114  }
1115  if(loc[2] < 6) transform(xcoord,ycoord,theta,phi,tof,trkNum);// transform and store
1116  }
1117 
1118  fCell = 0;
1119  fCal = 0;
1120 
1121  initArrays();
1122 
1123  itercell->Reset();
1124 
1125  setLoopVariables(0,0,0,0);
1126 
1127 
1128 
1129 
1130  while ((fCell=(HMdcGeantCell *)itercell->Next()) != NULL)
1131  {
1132  initArrays();
1133  loc[0] = fCell->getSector();
1134  loc[1] = fCell->getModule();
1135  loc[2] = fCell->getLayer();
1136  loc[3] = fCell->getCell();
1137 
1138 
1139  //######################### CHECK IF OBJECT EXISTS (EMBEDDING) #####################
1140  fCal = 0;
1141  fCal = (HMdcCal1Sim*)fCalCat->getObject(loc);
1142 
1143  resetCal1Real(); // reset digitizers variables, not cal1!
1144 
1145  if (fCal)
1146  { // if object exists before
1147 
1148  getCal1Real(); // copy real cal1 data to digitizers variables
1149  // consistency check
1150 
1151  if((getNHitsReal() == 2 && getTdcMode() == 1) ||
1152  (getNHitsReal() < 0 && getTdcMode() == 2) )
1153  {
1154  Warning("HMdcDigitizer:execute()","HMdcCalibater1 and HMdcDigitizer running in different tdc modes!");
1155  }
1156  }
1157  //##################################################################################
1158 
1159 
1160 
1161  // Digitisation procedure starts here:
1162 
1163 
1164  // First TDC signal
1165  Int_t nHits = fCell->getNumHits();
1166  for(Int_t ihit = 0; ihit < nHits; ihit ++)
1167  {
1168  fillArrays (ihit,loc[0],loc[1],fCell); // fill arrays with all variables needed
1169  setEfficiencyFlags(ihit,loc[0],loc[1],loc[2]); // checks for efficiency cuts and sets the propper statusflags
1170  //setTimeCutFlags (ihit,loc[0],loc[1],loc[2]); // checks time cuts and sets the propper statusflags
1171  }
1172 
1173 
1174  //########################### FILLING REAL DATA ##################################
1175  if(getEmbeddingMode() == 1 && getTime1Real() != -999)
1176  { // if embedding mode and a cell was filled before
1177  fillArraysReal(nHits); // fill the real data into the working arrays
1178  if(getTdcMode() == 2) nHits = nHits + 1; // count up the number of hits (1 Hit)
1179  else if(getTdcMode() == 1)nHits = nHits + 2; // count up the number of hits (2 Hits)
1180  }
1181  //################################################################################
1182 
1183  if (nHits > 1) select(nHits); // sort all hits by arrival time (tof + drifttime + wireOffset)
1184 
1185  resetListVariables();
1186 
1187  if(getNTuple())
1188  {
1189  // fill Ntuple with internal information of the Digitizer
1190  for(Int_t hit = 0; hit < NMAXHITS; hit ++)
1191  {
1192  if(getStatus(hit) == 0)continue;
1193  fillNTuple(loc[0],loc[1],loc[2],loc[3],hit,
1194  fCell,distance_time);
1195  }
1196  }
1197 
1198  //#################################### FILLING OUTPUT #######################################
1199 
1200  findFirstValidHit();
1201 
1202 
1203  if(!fCal)
1204  { // if object did not exist before allocate a new object
1205  fCal = (HMdcCal1Sim*)fCalCat->getSlot(loc);
1206  if (fCal)
1207  {
1208  fCal = new(fCal) HMdcCal1Sim;
1209  fCal->setAddress(loc[0],loc[1],loc[2],loc[3]);
1210  }
1211  else
1212  {
1213  Warning("HMdcDigitizer:execute()","CAL1SIM:getSlot(loc) failed!");
1214  }
1215  }
1216 
1217  //----------------------------------------- MODE1 AND MODE2 ---------------------------------------------------
1218  if(fCal)
1219  {
1220  if(getTdcMode() == 1 || getTdcMode() == 2)
1221  { // both TDC modes
1222  if(getFirstHit() != -999)
1223  {
1224  // if a valid hit was found
1225 
1226  //--------------------- switch table ----------------------------------------------------------
1227  // DTime1/2 contains drift time + error + tof + wireoffset:
1228  //
1229  // useTof : 0 +((Int_t)useTof-1 ) -> -1 tof will be substracted
1230  // 1 +((Int_t)useTof-1 ) -> 0 tof will not be substracted
1231  // useError : 0 +((Int_t)useError-1) -> -1 error will be substracted
1232  // 1 +((Int_t)useError-1) -> 0 error will not be substracted
1233  // useOffsets : 0 -((Int_t)useOffsets) -> 0 no offsets will be substracted
1234  // 1 -((Int_t)useOffsets) -> -1 offsets will be substracted
1235  // useWireOffset : 0 +((Int_t)useWireOffset-1) -> -1 wire offsets will be substracted
1236  // 1 +((Int_t)useWireOffset-1) -> 0 wire offsets will be included
1237  //---------------------------------------------------------------------------------------------
1238 
1239  fCal->setTime1(
1240  getDTime1(getFirstHit())
1241  + ( ((Int_t)getTofUse() - 1) * getTof(getFirstHit()) )
1242  + ( ((Int_t)getErrorUse() - 1) * getDTime1Err(getFirstHit()) )
1243  - ( ((Int_t)getOffsetsUse()) * getOffset(loc[1]) )
1244  + ( ((Int_t)getWireOffsetUse() - 1) * getWireOffset(getFirstHit()) ) );
1245 
1246  fCal->setNTrack1(getTrackN(getFirstHit()));
1247  fCal->setStatus1(getStatus(getFirstHit()));
1248  fCal->setAngle1(getAngle(getFirstHit()));
1249  fCal->setMinDist1(getMinimumDist(getFirstHit()));
1250  fCal->setError1(getDTime1Err(getFirstHit()));
1251  fCal->setTof1(getTof(getFirstHit()));
1252  fCal->setWireOffset1(getWireOffset(getFirstHit()));
1253  }
1254  else
1255  {
1256  fCal->setStatus1(findNonValidHit()); // no valid hit1 found
1257  }
1258  }
1259 
1260  //----------------------------------------- MODE2 --------------------------------------------------------------------
1261  if(getTdcMode() == 2)
1262  { // leading and trailing edge
1263  if(getFirstHit() != -999)
1264  { // if a valid hit was found
1265 
1266  fCal->setTime2(
1267  getDTime2(getFirstHit())
1268  + ( ((Int_t)getTofUse() - 1) * getTof(getFirstHit()) )
1269  + ( ((Int_t)getErrorUse() - 1) * getDTime2Err(getFirstHit()) )
1270  - ( ((Int_t)getOffsetsUse()) * getOffset(loc[1]) )
1271  + ( ((Int_t)getWireOffsetUse() - 1)* getWireOffset(getFirstHit()) ) );
1272 
1273  fCal->setNTrack2(getTrackN(getFirstHit())); // fill same track number as for time1
1274  fCal->setNHits(2); // second hit = trailing edge
1275  fCal->setStatus2(getStatus(getFirstHit())); // status is ok
1276  fCal->setAngle2(getAngle(getFirstHit()));
1277  fCal->setMinDist2(getMinimumDist(getFirstHit()));
1278  fCal->setError2(getDTime2Err(getFirstHit()));
1279  fCal->setTof2(getTof(getFirstHit()));
1280  fCal->setWireOffset2(getWireOffset(getFirstHit()));
1281  }
1282  else
1283  {
1284  fCal->setStatus2(findNonValidHit()); // no vaild hit2 found
1285  }
1286  }
1287 
1288  //----------------------------------------- MODE1 -------------------------------------------------------------------------
1289 
1290  if (nHits == 1 && getTdcMode() == 1) fCal->setNHits(-1); // if only one hit was detected
1291  else
1292  {
1293  if(nHits > 1 && getTdcMode() == 1 && getFirstHit() != -999)
1294  { // two times leading edge
1295  findSecondValidHit();
1296 
1297  if (getSecondHit() == -999 )
1298  {
1299  fCal->setNHits(-1); // if no valid hit2 was found
1300  }
1301  else
1302  {
1303  fCal->setTime2(
1304  getDTime1(getSecondHit())
1305  + ( ((Int_t)getTofUse() - 1) * getTof(getSecondHit()) )
1306  + ( ((Int_t)getErrorUse() - 1) * getDTime1Err(getSecondHit()) )
1307  - ( ((Int_t)getOffsetsUse()) * getOffset(loc[1]) )
1308  + ( ((Int_t)getWireOffsetUse() -1) * getWireOffset(getSecondHit()) ) );
1309 
1310  fCal->setNTrack2(getTrackN(getSecondHit())); // number of second track is stored
1311  fCal->setNHits(-2); // second valid hit was found
1312  fCal->setStatus2(getStatus(getSecondHit())); // status of hit2 is ok
1313  fCal->setAngle2(getAngle(getSecondHit()));
1314  fCal->setMinDist2(getMinimumDist(getSecondHit()));
1315  fCal->setError2(getDTime1Err(getSecondHit()));
1316  fCal->setTof2(getTof(getSecondHit()));
1317  fCal->setWireOffset2(getWireOffset(getSecondHit()));
1318  }
1319  }
1320  else if(nHits > 1 && getTdcMode() == 1)
1321  {
1322  fCal->setStatus2(findNonValidHit()); // no valid second hit was found
1323  }
1324  }
1325 
1326  //---------------------------------- FILL LIST OF TRACKS / STATUSFLAGS -----------------------------------------------
1327 
1328  fillTrackList(fCal); // fill list of tracks and statusflags
1329  // even if no valid hit was in
1330  }
1331  }
1332 
1333  //###################################### NOISE #########################################
1334  if(getNoiseUse())
1335  {
1336  // loop over all cells in actual existing Setup
1337  // and pick randomly cells.If a cell is selected
1338  // a random time is filled and the cell is stored
1339  // in the output. For cells filled by Geant hits
1340  // the noise time will be compared to the measured
1341  // time and if the noise comes earlier the real time
1342  // will be replaced (if noise mode 1 is selected)
1343 
1344  setLoopVariables(0,0,0,0);
1345 
1346  itercal1->Reset();
1347  Int_t sec,mod,lay,cell;
1348 
1349  while ((fCal = (HMdcCal1Sim *)itercal1->Next()) != NULL)
1350  {
1351  fCal->getAddress(sec,mod,lay,cell); // get existing object
1352  if(getNoiseMode() == 1 && ( gRandom->Rndm()<getNoiseLevel(mod)) )
1353  {
1354  // check if the time1 of the noise hit is smaller than time1 of the real hit
1355  // if this case is fullfilled the real hit will be overwritten by the noise hit.
1356  // if no valid hit was found the noise hit will be written.
1357 
1358  fillNoiseToGeantCells(mod,fCal); // fill this cell with noise if noise comes earlier
1359  }
1360  fillNoise(firstsec,firstmod,firstlay,firstcell,sec,mod,lay,cell); // fill randomly all cells before the object
1361  setLoopVariables(sec,mod,lay,cell + 1,kTRUE); // set the loop start no the actual value
1362  }
1363  fillNoise(firstsec,firstmod,firstlay,firstcell,5,3,5,999); // fill rest of noise cells after last real object
1364  }
1365  //######################################################################################
1366 
1367  //############################### TIMECUTS #############################################
1368  if(getTimeCutUse())
1369  {
1370  itercal1->Reset();
1371 
1372  while ((fCal = (HMdcCal1Sim *)itercal1->Next()) != NULL)
1373  {
1374  setTimeCutFlags(fCal);
1375  }
1376  }
1377  //######################################################################################
1378 
1379  return 0;
1380 }
1381 
1382 void HMdcDigitizer::fillArrays(Int_t ihit,Int_t sec,Int_t mod,HMdcGeantCell* fCell)
1383 {
1384  // All needed Arrays for the calculations are
1385  // filled (minimumdist,angle,tracknumber,tof,time1,time2,time1err,time2err)
1386  Int_t l = fCell->getLayer();
1387  Int_t c = fCell->getCell();
1388 
1389  setMinimumDist(ihit,fCell->getMinDist (ihit));
1390  setAngle (ihit,fCell->getImpactAngle(ihit));
1391  setTrackN (ihit,fCell->getNTrack (ihit));
1392  setTof (ihit,fCell->getTimeFlight (ihit));
1393  setWireOffset (ihit,fCell->getWireOffset (ihit));
1394  setEfficiency (ihit,fCell->getEfficiency (ihit));
1395  setTheta (ihit,fCell->getTheta (ihit));
1396  setCutEdge (ihit,fCell->getFlagCutEdge(ihit));
1397 
1399 
1400  setDTime1 (ihit,(Float_t)time1 * getScaleTime() + time1Error + getTof(ihit) + getWireOffset(ihit) + rndmoffsets[sec][mod][l][c]);
1401  setDTime1Err(ihit,time1Error);
1402 
1403  if(getDeDxUse())
1404  {
1405  // calculate the time2 need for Time over Threshold from the
1406  // energy loss of the particle. This is needed to get good
1407  // agreement to the experimental data. The conversion functions
1408  // are obtained from real data and used to calibrate the dEdX.
1409 
1411 
1412  //--------------------------------------------
1413  // get particle infos for dEdx calculation
1414  HGeantKine* kine = (HGeantKine*)fGeantKineCat->getObject(getTrackN(ihit) - 1);
1415  if(kine){
1416 
1417  //--------------------------------------------
1418  // now loop over all MDC hits of this track until you
1419  // find the corresponding hit or reach the end of the list
1420  kine->resetMdcIter(); // make sure that the iterator is at the beginning on the list
1421  HGeantMdc* gMdc = 0;
1422  Bool_t found = kFALSE;
1423 
1424  while((gMdc = (HGeantMdc*)kine->nextMdcHit()) != 0)
1425  {
1426  if(gMdc->getModule() == mod &&
1427  gMdc->getLayer() == l) {
1428  // found the correct one
1429  // important: do not check sector, some paticles
1430  // cross sector boundaries!
1431  found = kTRUE;
1432  break;
1433  }
1434  }
1435  if(!found) gMdc = 0;
1436  //--------------------------------------------
1437 
1438  //--------------------------------------------
1439  // get momentum of particle
1440  Float_t p = 0;
1441  if(gMdc){
1442  Float_t x,y,tof;
1443  gMdc->getHit(x, y, tof, p);
1444  }else{
1445  // if GeantMdc was not found take
1446  // momentum from kine instead
1447  p = kine->getTotalMomentum();
1448  Warning("fillArrays()","HGeantMdc object not found, take kine momentum instead!");
1449  }
1450  //--------------------------------------------
1451 
1452 
1453  //--------------------------------------------
1454  // efficiency scaling with dedx
1455  Float_t initFrac = 100.- getCellEffLevel(mod); // dedx > fBetaLow
1456  Double_t beta = HMdcDeDx2::beta(kine->getID(),p);
1457 
1458  if(useDeDxScaling && beta > fBetaLow){
1459  // do scaling with beta > fBetaLow
1460  // take care about very high dedx for beta close to 1
1461  Double_t dedx_low = fbetadEdx->Eval(fBetaLow);
1462  Double_t dedx = fbetadEdx->Eval(beta);
1463  if(dedx > dedx_low) dedx = dedx_low;
1464  initFrac *= dedx_low/dedx;
1465  }
1466  setFractionOfmaxCharge(ihit,initFrac); // will be rewritten in setEfficiencyFlags();
1467  //--------------------------------------------
1468 
1469  //--------------------------------------------
1470  // drift time error scaling with dedx
1471  if(useDeDxTimeScaling ) {
1472 
1473  Float_t scale = initFrac/(100.- getCellEffLevel(mod));
1474  scale+= (scale-1.) * scaleErrorMIPS[mod];
1475 
1476  time1Error = time1Error * scaleError[mod] * scale;
1477 
1478  setDTime1 (ihit,(Float_t)time1 * getScaleTime() + time1Error + getTof(ihit) + getWireOffset(ihit) + rndmoffsets[sec][mod][l][c]);
1479  setDTime1Err(ihit,time1Error);
1480  }
1481  //--------------------------------------------
1482 
1483  //--------------------------------------------
1484  // finally calulate time2 via the dEdX of the
1485  // particle
1486  Float_t t2;
1488  sec,mod,l,c,getAngle(ihit),getMinimumDist(ihit));
1489 
1490  if(TMath::Finite(t2) && t2 > 0){
1491  // if value was not NaN of Inf
1492  time2 = t2;
1493  }
1494  //--------------------------------------------
1495  }else {
1496  // if kine fails normal time2 will be used later....
1497  Error("fillArrays()","ZERO POINTER for kine object retrieved!");
1498  }
1499  }else{
1500  // calulate time2 from GARFIELD simulations
1502  }
1503 
1504 
1505  Float_t mytime2 = time2*getScaleTime() + time2Error + getTof(ihit) + rndmoffsets[sec][mod][l][c];
1506 
1507  if(mytime2 < getDTime1(ihit))
1508  { // make shure that time2 > time1
1509  setDTime2(ihit,time1 * getScaleTime() + time1Error + 20 + (10 * gRandom->Gaus(0,1)) + getTof(ihit) + getWireOffset(ihit) + rndmoffsets[sec][mod][l][c]);
1510  }
1511  else
1512  {
1513  setDTime2(ihit,time2 * getScaleTime() + time2Error + getTof(ihit) + getWireOffset(ihit) + rndmoffsets[sec][mod][l][c]);
1514  }
1515  setDTime2Err(ihit,time2Error);
1516 
1517 }
1519 {
1520  // All needed Arrays for the calculations are
1521  // filled for the REAL hits (minimumdist,angle,tracknumber,tof,time1,time2,time1err,time2err)
1522  Float_t def_val = -99;
1523 
1524  if(getTdcMode() == 2 && i < NMAXHITS-1)
1525  { // leading and trailing edge
1526  setMinimumDist(i,def_val);
1527  setAngle (i,def_val);
1529  setTof (i,-999);
1530 
1531  setDTime1 (i,getTime1Real());
1532  setDTime1Err (i,def_val);
1533 
1534  if(getTime2Real() > -998)
1535  { // if trailing edge has been measured
1536  setDTime2(i,getTime2Real());
1537  }
1538  else
1539  { // create dummy trailing edge
1540  setDTime2(i,getTime1Real() + 80);
1541  }
1542  setDTime2Err(i,def_val);
1543 
1544  setCutEdge(i,kFALSE);
1545  setWireOffset(i,0.);
1546  setEfficiency(i,1.);
1547  setTheta(i,0.);
1548  setStatus(i,3);
1550  }
1551  else if(getTdcMode() == 1 && i < NMAXHITS-2)
1552  { // two leading edges
1553  // first hit
1554  setMinimumDist(i,def_val);
1555  setAngle (i,def_val);
1557  setTof (i,-999);
1558 
1559  setDTime1 (i,getTime1Real());
1560  setDTime1Err (i,def_val);
1561 
1562  setDTime2 (i,-999);
1563  setDTime2Err (i,def_val);
1564 
1565  setCutEdge (i,kFALSE);
1566  setWireOffset (i,0.);
1567  setEfficiency (i,1.);
1568  setTheta(i,0.);
1569  setStatus (i,3);
1571 
1572  // second hit
1573  setMinimumDist(i + 1,def_val);
1574  setAngle (i + 1,def_val);
1576  setTof (i + 1,def_val);
1577 
1578  if(getTime2Real() > -998)
1579  { // if there has been a real second hit
1580  setDTime1(i + 1,getTime2Real());
1581  }
1582  else
1583  { // if there has been no second hit
1584  setDTime1(i + 1,1000);
1585  }
1586  setDTime1Err (i + 1,def_val);
1587 
1588  setDTime2 (i + 1,-999);
1589  setDTime2Err (i + 1,def_val);
1590 
1591  setCutEdge (i + 1,kFALSE);
1592  setWireOffset(i + 1,0.);
1593  setStatus (i + 1,3);
1594  setFractionOfmaxCharge(i + 1,0);
1595  }
1596  else
1597  {
1598  Warning("HMdcDigitizer:fillArraysReal()","real hit could not be stored to array,\n because the maximum has been exceeded!");
1599  }
1600 }
1601 void HMdcDigitizer::setEfficiencyFlags(Int_t ihit,Int_t sec,Int_t mod,Int_t lay)
1602 {
1603  // Cuts for cell efficiency layer efficiency and wire status are checked
1604  // and the statusflag of the cells are set correspondingly
1605  // Has to be done for sim tracks only!
1606  if(getTrackN(ihit) != gHades->getEmbeddingRealTrackId())
1607  {
1608 
1609  Float_t layEffPenalty = getEfficiency(ihit); // this number should be multiplied to layer Eff
1610 
1611  Float_t efflevel = getFractionOfmaxCharge(ihit);
1612  // only for sim hits
1613  if(evalWireStat(sec,mod,lay,loc[3]))
1614  { // if the wire is connected and working or wireStatUse=kFALSE
1615  if(getCellEffUse())
1616  {
1617  //--------------------------------------------
1618  // get particle infos for dEdx calculation
1619  setStatus (ihit,fCellEff->calcEfficiency(mod,getMinimumDist(ihit),getAngle(ihit),efflevel));
1620  setFractionOfmaxCharge(ihit,fCellEff->calcEffval(mod,getMinimumDist(ihit) ,getAngle(ihit),efflevel));
1621  }
1622  else
1623  {
1624  setStatus(ihit,1);
1625  setFractionOfmaxCharge(ihit,100);
1626  }
1627  // Efficiency of MDC layers can be less then 100%...
1628  Float_t eff = fDigitPar->getLayerEfficiency (sec,mod,lay);
1629  if(useLayerThickness) eff*= layEffPenalty; // loss scaled by theta (account for impact angle)
1630 
1631 
1632 
1633  if(fWireStat && useWireStatEff){ eff *= fWireStat->getEfficiency(sec,mod,lay,loc[3]);}
1634 
1635  Float_t valRand = 1;
1636 
1637  Int_t ind = findTrack(getTrackN(ihit));
1638  if(ind == -1) {
1639  Error("setEfficiencyFlags()","tracknumber %i not Found",getTrackN(ihit));
1640  } else if (vLayEff[ind].ct[sec][mod][lay] == 1){ // normal tracks
1641  valRand = vLayEff[ind].eff[sec][mod][lay];
1642  } else { // for curling tracks
1643  valRand = gRandom->Rndm();
1644  }
1645 
1646  //-------------------------------------
1647 
1648 
1650  // do scaling with beta > fBetaLow
1651  Double_t initFrac = 100.- getCellEffLevel(mod); // dedx > fBetaLow
1652  Double_t scale = efflevel/initFrac; // get scaling factor back ( > 1 for mip)
1653  Double_t effScale = fDigitPar->getLayerEfficiencyScale(sec,mod,lay); // max additional loss for mips ( 0.98 for 2% reduction)
1654 
1655  Double_t dedx_low = fbetadEdx->Eval(fBetaLow);
1656  Double_t dedx_mip = fbetadEdx->Eval(0.95);
1657  Double_t scaleMip = dedx_low/dedx_mip;
1658  eff -= (( scale - 1. )/(scaleMip -1.))*(1.-effScale);
1659  if(eff < 0) eff = 0;
1660  }
1661  //-------------------------------------
1662 
1663 
1664 
1665  if(valRand > eff)
1666  {
1667  switch (getStatus(ihit))
1668  {
1669  case 1: setStatus(ihit,-2); // if it is kicked out by layer efficiency
1670  break;
1671  case -1: setStatus(ihit,-1); // if it was kicked out by cell efficiency
1672  break;
1673  default : setStatus(ihit,-7); // just control
1674  break;
1675  }
1676 
1677  }
1678  }
1679  else
1680  { // if wire is not connected or dead
1681  setStatus(ihit,-3);
1682  setFractionOfmaxCharge(ihit,0);
1683  }
1684  }
1685  else
1686  {
1687  // real hits should allways be used
1688  setStatus(ihit,3);
1689  setFractionOfmaxCharge(ihit,0);
1690  }
1691 }
1692 
1693 void HMdcDigitizer::setTimeCutFlags(Int_t ihit,Int_t sec,Int_t mod,Int_t lay)
1694 {
1695  // Cuts for drit times and the statusflag of the cells are set
1696  // correspondingly. Has to be done for sim tracks only!
1697 
1698  if(getTimeCutUse())
1699  {
1700  if(getTrackN(ihit) != gHades->getEmbeddingRealTrackId())
1701  {
1702  // only for sim hits
1703  if( getStatus(ihit) > 0 &&
1704  (
1705  !fTimeCut->cutTime1 (sec,mod,getDTime1(ihit)) ||
1706  !fTimeCut->cutTime2 (sec,mod,getDTime2(ihit)) ||
1707  !fTimeCut->cutTimesDif(sec,mod,getDTime1(ihit),getDTime2(ihit))
1708  )
1709  )
1710  {
1711  // drift time did not pass the cuts , set the propper statusflag
1712  setStatus(ihit,-5);
1713  }
1714  }
1715  }
1716 }
1718 {
1719  // Cuts for drit times and the statusflag of the cells are set
1720  // correspondingly. Has to be done for sim tracks only!
1721 
1722  if(getTimeCutUse())
1723  {
1724  if( cal1->getStatus1() > 0 &&
1725  (
1726  !fTimeCut->cutTime1 (cal1) ||
1727  !fTimeCut->cutTime2 (cal1) ||
1728  !fTimeCut->cutTimesDif(cal1)
1729  )
1730  )
1731  {
1732  // drift time did not pass the cuts , set the propper statusflag
1733  cal1->setStatus1(-5);
1734  cal1->setStatus2(-5);
1735  }
1736  }
1737 }
1738 Bool_t HMdcDigitizer::evalWireStat(Int_t sec,Int_t mod,Int_t lay,Int_t cell)
1739 {
1740  // gets the status of the wire from HMdcWireStat.
1741  // returns kFALSE if wire is dead or not connected.
1742 
1743  Bool_t result = kTRUE;
1744  Int_t stat = -99;
1745  if(getWireStatUse()) {
1746  stat = fWireStat->getStatus(sec,mod,lay,cell);
1747  (stat > 0)? result = kTRUE : result = kFALSE;
1748  }
1749  return result;
1750 }
1751 
1753 {
1754  // init working arrays with default values
1755 
1756  for(Int_t i = 0; i < NMAXHITS; i ++) // reset arrays
1757  {
1758  dTime [i] = 0.;
1759  dTime2 [i] = 0.;
1760  dTimeErr [i] = 0.;
1761  dTime2Err [i] = 0.;
1762  minimumdist [i] = 0.;
1763  track [i] = -99;
1764  timeOfFlight [i] = 0.;
1765  angle [i] = 0.;
1766  statusflag [i] = 0;
1767  fractionOfmaxCharge[i] = 0.;
1768  cutEdge [i] = kFALSE;
1769  wireOffset [i] = 0.;
1770  efficiency [i] = 1.;
1771  theta [i] = 0.;
1772  }
1773 }
1774 
1776 {
1777  // reset the list variables for the search of valid
1778  // hits
1779  setFirstHit (-999); // number of first valid hit
1780  setSecondHit (-999); // number of second valid hit
1781  setFirstTime2(-999); // time2 of first valid hit
1782  setEndList1 (-999); // last hit in window of first valid hit
1783 };
1785 {
1786  // reset the local variables for the
1787  // real cal1 hit
1788  setTime1Real(-999);
1789  setTime2Real(-999);
1790  setNHitsReal(0);
1791 };
1792 
1794 {
1795  // copy time1, time2 and nhits from
1796  // real cal1 object to local variables
1800 }
1801 
1802 
1803 void HMdcDigitizer::fillNTuple(Int_t sec,Int_t mod,Int_t lay,Int_t cell,Int_t ihit,
1804  HMdcGeantCell* fCell, TNtuple* distance_time)
1805 {
1806  // The NTuple is filled with internal data of the digitizer
1807 
1808  distance_time->Fill(sec,mod,lay,cell,
1809  getMinimumDist(ihit),
1810  getAngle(ihit),
1811  getDTime1(ihit),
1812  getDTime1Err(ihit),
1813  getDTime2(ihit),
1814  getDTime2Err(ihit),
1815  getTof(ihit),
1816  getCutEdge(ihit),
1817  getStatus(ihit),
1818  getTrackN(ihit),
1820  );
1821 }
1822 void HMdcDigitizer::fillNTuple(Int_t sec,Int_t mod,Int_t lay,Int_t cell,
1823  Float_t time, Float_t time2,
1824  Int_t status)
1825 {
1826  // The NTuple is filled with internal data of the digitizer
1827  // in the case of noise generation
1828  distance_time->Fill(sec,mod,lay,cell,
1829  -1,
1830  -1,
1831  time ,0,
1832  time2,0,
1833  0,
1834  0,
1835  status,
1836  -99,
1837  100);
1838 }
1839 
1841 {
1842  // A random time in a specified time window
1843  // for the noise simulation is calculated
1844  Float_t time1Noise = -999;
1845  time1Noise = (gRandom->Rndm() * (getNoiseRangeHi(mod)-getNoiseRangeLo(mod))) + getNoiseRangeLo(mod);
1846  return time1Noise;
1847 }
1849 {
1850  // A random time in a specified time window
1851  // for the noise simulation is calculated
1852  Float_t time2Noise = -999;
1853  if(gRandom->Rndm() < getNoiseWhiteRatio())
1854  {
1855  time2Noise = getTime1Noise() + gRandom->Rndm() * getNoiseWhiteWidth();
1856  }
1857  else {
1858  time2Noise = getTime1Noise() + gRandom->Rndm() * getNoiseBandWidth();
1859  }
1860  return time2Noise;
1861 }
1862 void HMdcDigitizer::fillNoiseLists(HMdcCal1Sim* cal1,Int_t statval,Int_t geant)
1863 {
1864 
1865  // sets the lists of status and tracks
1866  // statval is put to the first entry of the status list
1867  // if geant==1 (cell was Geant hit before), the original
1868  // track numbers and the status flags (except the first) are kept
1869 
1870  if(geant == 0)
1871  { // noise only
1872  Int_t dummystat [5] = { 0, 0, 0, 0, 0};
1873  Int_t dummytrack[5] = {-99,-99,-99,-99,-99};
1874  dummystat[0] =statval;
1875 
1876  cal1->setStatusList(dummystat); // store array in cal1sim level
1877  cal1->setTrackList(dummytrack); // store array in cal1sim level
1878  }
1879  else
1880  { // noise into Geant cell
1881  Int_t* mylist = cal1->getStatusList();
1882  mylist[0] = statval;
1883  }
1884 
1885 }
1887 {
1888  // If timenoise < time of the first valid GEANT hit
1889  // the time is replaced by timenoise and the
1890  // statusflag is changed from 1 (valid) to 2 (valid but noise)
1891 
1892 
1895 
1896  if(getTime1Noise() < cal1->getTime1())
1897  {
1898  cal1->setStatus1(2); // noise hit
1899  cal1->setTime1(getTime1Noise()); // old time1 is replaced by noise
1900  cal1->setTime2(getTime2Noise()); // old time2 is replaced by noise
1901  cal1->setError1(-99); // noise has no error
1902  cal1->setError2(-99); // noise has no error
1903  cal1->setTof1(-999); // tof->0 to put the correct noise time to the output
1904  cal1->setTof2(-999); // tof->0 to put the correct noise time to the output
1905  cal1->setWireOffset1(-99); // noise has no wire offset
1906  cal1->setWireOffset2(-99); // noise has no wire offset
1907  cal1->setStatus1(2); // noise has no wire offset
1908  cal1->setStatus2(2); // noise has no wire offset
1909  cal1->setAngle1(-99); // no impact angle
1910  cal1->setAngle2(-99); // no impact angle
1911  cal1->setMinDist1(-99); // no min dist
1912  cal1->setMinDist2(-99); // no min mindist
1913  cal1->setNTrack1(-99); // no track id
1914  cal1->setNTrack2(-99); // no track id
1915  fillNoiseLists(cal1,-4,1); // fill list of status/tracks
1916  }
1917 }
1918 void HMdcDigitizer::setLoopVariables(Int_t s,Int_t m,Int_t l,Int_t c,Bool_t check)
1919 {
1920  if(check)handleOverFlow(s,m,l,c);
1921  else {
1922  firstsec = s;
1923  firstmod = m;
1924  firstlay = l;
1925  firstcell = c;
1926  }
1927 }
1928 void HMdcDigitizer::handleOverFlow(Int_t firsts, Int_t firstm, Int_t firstl, Int_t firstc)
1929 {
1930  // if last cell in Layer has been reached
1931  // the next valid cell in setup has to be taken
1932 
1933  if(firstc>(*geomstruct)[firsts][firstm][firstl])
1934  {
1935  // find next valid module
1936 
1937  if(firstl < 5)
1938  { // just switch to next layer
1939  setLoopVariables(firsts,firstm,firstl + 1,0);
1940  }
1941  else
1942  { // if last layer, we have to move to next valid module
1943  Int_t found = 0;
1944  for(Int_t i = firsts; i < 6; i ++)
1945  {
1946  for(Int_t j = firstm; j < 4; j ++)
1947  {
1948  if(testMdcSetup(i,j))
1949  { // if a valid module in this sector has been found
1950  found ++;
1951  if(found == 1) setLoopVariables(i,j,0,0);
1952  }
1953  }
1954  }
1955  // if no valid module found switch to last ( will be skipped : 500 < lastcell)
1956  if(found == 0) setLoopVariables(firsts,firstm,firstl,500);
1957  }
1958  } else setLoopVariables(firsts,firstm,firstl,firstc);
1959 }
1960 
1961 void HMdcDigitizer::fillNoise(Int_t firsts, Int_t firstm, Int_t firstl, Int_t firstc,
1962  Int_t lastsec, Int_t lastmod, Int_t lastlay, Int_t lastcell)
1963 {
1964  // Fills the noise cells to Cal1Sim up to the next GEANT Cell
1965  // and the rest of the noise cells after the last GEANT Cell (if
1966  // input lastcell==999).
1967 
1968  fCalnoise = 0;
1969  locnoise.set(4,0,0,0,0);
1970 
1971  if(lastcell != 999) handleOverFlow(firsts,firstm,firstl,firstc);
1972 
1973  for (Int_t sec = firstsec; sec <= lastsec; sec ++)
1974  {
1975  if(sec > 5) continue;
1976  for (Int_t mod = firstmod; mod <= lastmod; mod ++)
1977  {
1978  if(mod > 3) continue;
1979  // test if module is existing in current setup
1980  if(!testMdcSetup(sec,mod) )continue;
1981 
1982  for (Int_t lay = firstlay; lay <= lastlay; lay ++)
1983  {
1984  if(lay > 5) continue;
1985  if(lastcell != 999)
1986  {
1987  for (Int_t cell = firstcell; cell < lastcell; cell ++)
1988  {
1989  if(cell > (*geomstruct)[sec][mod][lay]) continue;
1990 
1991  if(evalWireStat(sec,mod,lay,cell))
1992  { // if wire is connected and working
1993  if(gRandom->Rndm()<getNoiseLevel(mod))
1994  {
1995  locnoise[0] = sec;
1996  locnoise[1] = mod;
1997  locnoise[2] = lay;
1998  locnoise[3] = cell;
1999 
2000  fCalnoise = (HMdcCal1Sim*)fCalCat->getSlot(locnoise);
2001  if (fCalnoise)
2002  {
2004  fCalnoise->setAddress(sec,mod,lay,cell);
2005  if (getTdcMode() == 1)
2006  {
2007  fCalnoise->setNHits(-1);
2008  fCalnoise->setStatus1(2);
2009  fCalnoise->setStatus2(-3);
2010 
2011 
2013  setTime2Noise(-999);
2015 
2016  if(getNTuple())
2017  {
2020  }
2021  }
2022  else if(getTdcMode() == 2)
2023  {
2024  fCalnoise->setNHits(2);
2025  fCalnoise->setStatus1(2);
2026  fCalnoise->setStatus2(2);
2031 
2032  if(getNTuple())
2033  {
2036  }
2037  }
2039  }
2040  }
2041  }
2042  }
2043  }
2044  if(lastcell == 999)
2045  { // fill up to the last existing wire
2046  HMdcLayerGeomParLay& layernoise = (*fDigitGeomPar)[sec][mod][lay];
2047  Int_t nWires = layernoise.getNumWires(); // number of wires per layer
2048 
2049  for (Int_t cell = firstc; cell < nWires; cell ++)
2050  {
2051  if(evalWireStat(sec,mod,lay,cell))
2052  { // if wire is connected and working
2053  if(gRandom->Rndm() < getNoiseLevel(mod))
2054  {
2055  locnoise[0] = sec;
2056  locnoise[1] = mod;
2057  locnoise[2] = lay;
2058  locnoise[3] = cell;
2059 
2060  fCalnoise = (HMdcCal1Sim*)fCalCat->getSlot(locnoise);
2061  if(fCalnoise)
2062  {
2064  fCalnoise->setAddress(sec,mod,lay,cell);
2065  if(getTdcMode() == 1)
2066  {
2067  fCalnoise->setNHits(-1);
2068  fCalnoise->setStatus1(2);
2069  fCalnoise->setStatus2(-3);
2071  setTime2Noise(-999);
2073 
2074  if(getNTuple())
2075  {
2078  }
2079  }
2080  else if(getTdcMode() == 2)
2081  {
2082  fCalnoise->setNHits(2);
2083  fCalnoise->setStatus1(2);
2084  fCalnoise->setStatus2(2);
2089 
2090  if(getNTuple())
2091  {
2094 
2095  }
2096  }
2098  }
2099  }
2100  }
2101  }
2102  }
2103  }
2104  }
2105  }
2106 }
2107 
2109 {
2110  // fills track list and status list for hits in both tdc modes
2111  Int_t array [5];
2112  Int_t array1[5];
2113 
2114  for(Int_t i = 0; i < 5; i ++)
2115  {
2116  array [i] = getTrackN(i);
2117  array1[i] = getStatus(i);
2118  }
2119  fCal->setTrackList (array); // store array in cal1sim level
2120  fCal->setStatusList(array1); // store array in cal1sim level
2121 }
2123 {
2124  // Function to find the first valid hit (statusflag > 0) inside the
2125  // array for both tdc modes. Returns the number of the element of the
2126  // first valid hit and last hit inside the time window to variables.
2127 
2128  Int_t hit = 0;
2129  Int_t lasthit = 0;
2130  while(getStatus(hit) <= 0) // find first valid hit
2131  {
2132  lasthit ++;
2133  hit ++;
2134  if(hit == NMAXHITS)
2135  {
2136  // if last element is reached without found
2137  // condtion set flags and break
2139  break;
2140  }
2141  }
2142  if(hit < NMAXHITS)
2143  {
2144  while(lasthit < NMAXHITS && getDTime1(lasthit) <= getDTime2(hit))
2145  {
2146  lasthit ++; // last hist which falls into window of first hit
2147  }
2148  // set output values if condition was true
2149  setFirstHit(hit);
2150  setFirstTime2(getDTime2(hit));
2151 
2152  if(lasthit < NMAXHITS)
2153  {
2154  setEndList1(lasthit);
2155  }
2156  else
2157  {
2158  setEndList1(-999);
2159  }
2160  }
2161 
2162 }
2164 {
2165  // Function to find the second valid hit (statusflag > 0) inside the
2166  // array for tdc mode1. Returns the number of the element of the second
2167  // valid hit
2168 
2169  Int_t hit = getEndList1() + 1;
2170  if(hit < NMAXHITS && getEndList1() != -999) // make sure that it is not last element and a valid first hit exist
2171  {
2172  while(getStatus(hit) <= 0)
2173  {
2174  // stop if status=1 and second hit starts after first hit ends
2175  hit ++;
2176  if(hit == NMAXHITS)
2177  {
2178  // if last element is reached without found
2179  // condtion set flags and break
2180  setSecondHit(-999);
2181  break;
2182  }
2183  }
2184  if(hit < NMAXHITS)
2185  {
2186  // set output values if condition was true
2187  setSecondHit(hit);
2188  }
2189  }
2190  else
2191  {
2192  // function was called with las element
2193  // and skipped to end => no valid second hit found
2194  setSecondHit(-999);
2195  }
2196 }
2198 {
2199  // Function to find the first valid hit (statusflag > 0) inside the
2200  // array for both tdc modes. Returns the number of the element of the
2201  // first valid hit and last hit inside the time window to variables.
2202 
2203  Int_t hit = 0;
2204  Int_t foundTimeCut = 0;
2205 
2206  while(getStatus(hit) <= 0) // find first valid hit
2207  {
2208  if(getStatus(hit) == -5 ) foundTimeCut ++;
2209 
2210  hit ++;
2211 
2212  if(hit == NMAXHITS)
2213  {
2214  break;
2215  }
2216  }
2217  if(hit == NMAXHITS)
2218  { // reached end and did not find a valid hit
2219  return foundTimeCut > 0 ? -5 : -3;
2220  } else { return -7; }
2221 
2222 }
2223 
2224 void HMdcDigitizer::select(Int_t nHits)
2225 {
2226  // Puts the drift time values into increasing order.
2227  // Orders the corresponding track number, time of flight, statusflag
2228  // and impact angle etc accordingly
2229 
2230  register Int_t a,b,c;
2231  Int_t exchange;
2232  Float_t t;
2233  Float_t t2;
2234  Float_t tErr;
2235  Float_t t2Err;
2236 
2237  Float_t flight;
2238  Float_t angleLocal;
2239  Int_t statlocal;
2240  Int_t tracklocal;
2241  Float_t mindistlocal;
2242  Bool_t cutEdgelocal;
2243  Float_t fractionlocal;
2244  Float_t wireOffsetlocal;
2245 
2246  if(nHits <= NMAXHITS)
2247  {
2248  for(a = 0; a < nHits - 1; ++ a)
2249  {
2250  exchange = 0;
2251  c = a;
2252 
2253  t = dTime[a];
2254  tErr = dTimeErr[a];
2255  t2 = dTime2[a];
2256  t2Err = dTime2Err[a];
2257  tracklocal = track[a];
2258  flight = timeOfFlight[a];
2259  angleLocal = angle[a];
2260  statlocal = statusflag[a];
2261  mindistlocal = minimumdist[a];
2262  cutEdgelocal = cutEdge[a];
2263  fractionlocal = fractionOfmaxCharge[a];
2264  wireOffsetlocal = wireOffset[a];
2265 
2266  for(b=a+1;b<nHits;++b)
2267  {
2268  if(dTime[b]<t)
2269  {
2270  c = b;
2271 
2272  t = dTime[b];
2273  tErr = dTimeErr[b];
2274  t2 = dTime2[b];
2275  t2Err = dTime2Err[b];
2276  tracklocal = track[b];
2277  flight = timeOfFlight[b];
2278  angleLocal = angle[b];
2279  statlocal = statusflag[b];
2280  mindistlocal = minimumdist[b];
2281  cutEdgelocal = cutEdge[b];
2282  fractionlocal = fractionOfmaxCharge[b];
2283  wireOffsetlocal = wireOffset[b];
2284 
2285  exchange = 1;
2286  }
2287  }
2288  if(exchange)
2289  {
2290  dTime[c] = dTime[a];
2291  dTime[a] = t;
2292  dTimeErr[c] = dTimeErr[a];
2293  dTimeErr[a] = tErr;
2294  dTime2[c] = dTime2[a];
2295  dTime2[a] = t2;
2296  dTime2Err[c] = dTime2Err[a];
2297  dTime2Err[a] = t2Err;
2298  track[c] = track[a];
2299  track[a] = tracklocal;
2300  timeOfFlight[c] = timeOfFlight[a];
2301  timeOfFlight[a] = flight;
2302  angle[c] = angle[a];
2303  angle[a] = angleLocal;
2304  statusflag[c] = statusflag[a];
2305  statusflag[a] = statlocal;
2306  minimumdist[c] = minimumdist[a];
2307  minimumdist[a] = mindistlocal;
2308  cutEdge[c] = cutEdge[a];
2309  cutEdge[a] = cutEdgelocal;
2311  fractionOfmaxCharge[a] = fractionlocal;
2312  wireOffset[c] = wireOffset[a];
2313  wireOffset[a] = wireOffsetlocal;
2314  }
2315  }
2316 
2317  }
2318  else
2319  {
2320  Warning("HMdcDigitizer:select(nHits)","nHits > 15! Entries >15 skipped! ");
2321  }
2322 }
2324 {
2325  // Gets Mdc detector setup
2326 
2327  HMdcDetector* mdcDet=(HMdcDetector*)(((HSpectrometer*)(gHades->getSetup()))->getDetector("Mdc"));
2328  if (!mdcDet)
2329  {
2330  Error("HMdcDigitizer::getMdcSetup()","Mdc-Detector setup (gHades->getSetup()->getDetector(\"Mdc\")) missing.");
2331  }
2332  for(Int_t s = 0; s < 6; s ++) {
2333  for(Int_t m = 0; m < 4; m ++) {
2334  if (!mdcDet->getModule(s, m)) setup[s][m] = 0;
2335  if ( mdcDet->getModule(s, m)) setup[s][m] = 1;
2336  }
2337  }
2338 }
2339 
2340 Bool_t HMdcDigitizer::testMdcSetup(Int_t s, Int_t m)
2341 {
2342  // Tests the Mdc setup if the modules are present
2343  // in the running analysis
2344 
2345  Bool_t result=kFALSE;
2346  if(setup[s][m] == 0) result = kFALSE;
2347  if(setup[s][m] == 1) result = kTRUE;
2348  return result;
2349 }
2350 Bool_t HMdcDigitizer::transform(Float_t xcoor,Float_t ycoor,Float_t theta,
2351  Float_t phi ,Float_t tof ,Int_t trkNum) {
2352  // Gets the x,y coordinates, theta and phi, time of flight and track number.
2353  // From the coordinates and angles the hits in the cells are calculated.
2354  // All needed parameters are taken from HMdcLayerGeomPar and HMdcDigitPar
2355  // containers.
2356 
2357  // in HMdcCal2ParSim:
2358  // Input is the angle of the track (alphaTrack:90 degree for perpendicular impact),which
2359  // has to be recalculated to the angle of minimum drift distance (alphaDrDist:0 degree for
2360  // perpendicular impact).
2361  // y ^
2362  // | |------------*----| cathod plane
2363  // | | cell * |
2364  // | | / * |
2365  // | | /90 * |
2366  // | | driftDist/ *|
2367  // | | / | *
2368  // --|--|--------*^-|-----|*---------> sense/potential plane
2369  // | | | | * x
2370  // | | alphaDrDist| *
2371  // | |/ * alphaDriftDist=90-alphaTrack
2372  // | alphaTrack / *
2373  // |-----------------| * track cathod plane
2374  //
2375  // angles must be between 0 and 90 degree, all other angles have to be shifted
2376  // before calling the function.
2377 
2378  HMdcSizesCellsLayer &sclayer = (*fsizescells)[loc[0]][loc[1]][loc[2]];
2379 
2380  Int_t nCmin,nCmax;
2381  if( !sclayer.calcCrCellsGeantMdc(xcoor,ycoor,theta,phi,nCmin,nCmax) ) return kFALSE;
2382 
2383  Float_t effPenalty = effLayerThickness(xcoor,ycoor,theta, phi,loc[0],loc[1],loc[2]);
2384 
2385  //Float_t eff = calcEfficiencyAtLayerEdge(xorg,yorg,loc[0],loc[1],loc[2]);
2386  Float_t halfPitch = sclayer.getHalfPitch();
2387  Float_t halfCatDist = sclayer.getHalfCatDist();
2388 
2389  for (loc[3] = nCmin; loc[3] <= nCmax; loc[3] ++) {
2390 
2391  Float_t yDist = sclayer.getYinRotLay(loc[3],xcoor,ycoor) - sclayer.calcWireY(loc[3]);
2392  Float_t wOrient = sclayer.getWireOrient(loc[3]) * pi;
2393  Float_t ctanalpha = tan(theta * pi) * sin(phi * pi - wOrient);
2394 
2395  // recalculate the angle to the coordinatessystem of HMdcCal2ParSim
2396  myalpha = 90. - fabs(atan(ctanalpha) * TMath::RadToDeg());
2397 
2398  Float_t sinAlpha = sqrt(1. / (1. + ctanalpha * ctanalpha));
2399  Float_t cosAlpha = sqrt(1. - sinAlpha * sinAlpha);
2400 
2401  Float_t per = fabs(yDist * sinAlpha);// minimum distance of track to the wire
2402 
2403  Bool_t flagCutEdge = kFALSE;
2404  if(per * sinAlpha > halfPitch) { // check if per is inside cell (y)
2405 
2406  flagCutEdge = kTRUE;
2407 
2408  } else if(per * cosAlpha > halfCatDist) { // check if per is inside cell (z)
2409 
2410  flagCutEdge = kTRUE;
2411  }
2412 
2413  Float_t wireOffset = 0;
2414  if(getWireOffsetUse()) {
2415  // calculate the time needed by the signal to propagate to the tdc
2416  HMdcSizesCellsCell& mycell = sclayer[loc[3]];
2417  if(&mycell != NULL && mycell.getReadoutSide() != '0') {
2418  Float_t x_wire = sclayer.getXinRotLay(loc[3],xcoor,ycoor);
2419  wireOffset = getSignalSpeed() * mycell.getSignPath(x_wire);
2420  }
2421  }
2422  storeCell(per,tof,myalpha,trkNum,flagCutEdge,wireOffset,effPenalty,theta);//store the final values in container
2423  }
2424  return kTRUE;
2425 }
2426 
2427 void HMdcDigitizer::storeCell(Float_t per,Float_t tof,Float_t myangle,Int_t trkNum
2428  ,Bool_t flagCutEdge,Float_t wireOffset,Float_t eff,Float_t theta)
2429 {
2430  // Puts the data (minimum distance, time of flight, impact angle,
2431  // track number, flagCutEdge) to HMdcGeantCell Category
2432 
2433  hit = (HMdcGeantCell*)fGeantCellCat->getObject(loc);
2434  if (!hit) {
2435  hit = (HMdcGeantCell*)fGeantCellCat->getSlot(loc);
2436  hit = new(hit) HMdcGeantCell;
2437  }
2438  Int_t nHit;
2439  nHit = hit->getNumHits();
2440  if (nHit < NMAXHITS ) { // only the first 15 hits are stored
2441  hit->setSector(loc[0]);
2442  hit->setModule(loc[1]);
2443  hit->setLayer(loc[2]);
2444  hit->setCell(loc[3]);
2445  hit->setNumHits(nHit + 1);
2446  hit->setMinDist(per,nHit);
2447  hit->setTimeFlight(tof,nHit);
2448  hit->setImpactAngle(myangle,nHit);
2449  hit->setNTrack(trkNum,nHit);
2450  hit->setFlagCutEdge(flagCutEdge,nHit);
2451  hit->setWireOffset(wireOffset,nHit);
2452  hit->setEfficiency(eff,nHit);
2453  hit->setTheta(theta,nHit);
2454  }
2455  else
2456  {
2457  Warning("HMdcDigitizer:storeCell()","hit could not be stored in HMdcGeantCell ,\n because number of hits exceeded the maximum!");
2458  }
2459 }
2460 void HMdcDigitizer::initOffsets(TString filename)
2461 {
2462  // if createoffsets=kTRUE (setCreateOffsets()) a gausian distribution arround 0 with
2463  // sigma = sigmaoffsets is created (setSigmaOffsets(Float_t sig)). The values are written
2464  // to a ascii file "filename" for future use (if this file exists, it
2465  // will be over written!).
2466  // If createoffsets=kFALSE the offsets will not be recreated and instead the digitizer will
2467  // read them from ascii file "filename".
2468  // Format : sector module layer cell offset
2469  if(createoffsets)
2470  { // create the random offsets
2471  for(Int_t s = 0;s < 6; s ++){
2472  for(Int_t m = 0; m < 4; m ++){
2473  for(Int_t l = 0; l < 6; l ++){
2474  for(Int_t c = 0; c < 220; c ++){
2475  rndmoffsets[s][m][l][c] = gRandom->Gaus(0.,getSigmaOffsets());
2476  }
2477  }
2478  }
2479  }
2480 
2481  if(filename.CompareTo("") == 0)
2482  {
2483  Warning("HMdcDigitizer:initOffsets()","No file name specified, offsets will not be written to file!");
2484  }
2485  else
2486  {
2487  FILE* ascii=fopen(filename,"w");
2488  for(Int_t s = 0; s < 6; s ++){
2489  for(Int_t m = 0; m < 4; m ++){
2490  for(Int_t l = 0; l < 6; l ++){
2491  for(Int_t c = 0; c <220; c ++){
2492  fprintf(ascii,"%i %i %i %3i %7.3f \n",s,m,l,c,rndmoffsets[s][m][l][c]);
2493  }
2494  }
2495  }
2496  }
2497  fclose(ascii);
2498  }
2499  }
2500  else
2501  {
2502  FILE* ascii = fopen(filename,"r");
2503  if(!ascii)
2504  {
2505  Warning("HMdcDigitizer:initOffsets()","Specified file %s does not exist, offsets will be 0.0.!",filename.Data());
2506  }
2507  else
2508  {
2509  cout<<"HMdcDigitizer:initOffsets() Reading offset table from file "<<filename.Data()<<endl;
2510  Char_t line[400];
2511 
2512  while(1)
2513  {
2514  Int_t s,m,l,c;
2515  Float_t off;
2516  if(feof(ascii)) break;
2517  Bool_t res=fgets(line, sizeof(line), ascii);
2518  if(!res)cout<<"initOffsets: cannot read next line!"<<endl;
2519  sscanf(line,"%i %i %i %i %f",&s,&m,&l,&c,&off);
2520  rndmoffsets[s][m][l][c] = off;
2521  }
2522  fclose(ascii);
2523  }
2524  }
2525  offsetsCreated = kTRUE;
2526 }
2527 
2529 {
2530  // returns index of track in array
2531  // if track is not found returns -1
2532 
2533  for(UInt_t i = 0; i < vLayEff.size(); i ++){
2534  if(vLayEff[i].trackNum == trk) return i;
2535  }
2536  return -1;
2537 }
2538 
2539 Float_t HMdcDigitizer::effLayerThickness(Float_t xcoor,Float_t ycoor,Float_t th,Float_t ph,Int_t s,Int_t m,Int_t l)
2540 {
2541  Float_t effmin = fDigitPar ->getLayerEfficiencyThickness(s,m,l);
2542  if(effmin==0) return 1;
2543  const Float_t effmax = 1.00;
2544 
2545  HMdcSizesCellsMod& sizescellsMod = (*fsizescells)[s][m];
2546  HMdcSizesCellsLayer& sizescellsLay = (*fsizescells)[s][m][l];
2547 
2548  Float_t Lmin = layEff.Lmin[s][m][l];
2549  Float_t Lmax = layEff.Lmax[s][m][l];
2550 
2551  if(Lmin < 0 || Lmax < 0) {
2552 
2553  Error("effLayerThickness()","Lmin or Lmax not set Lmin = %f , Lmax = %f ! ",Lmin,Lmax);
2554  return 1;
2555  }
2556 
2557  //-------------------------------------------------------
2558  // calculate straight line in sec coordinate sys
2559  // from Geant MDC
2560  Double_t x1,y1,z1,x2,y2,z2;
2561 
2562  Double_t theta = th*TMath::DegToRad();
2563  Double_t phi = ph*TMath::DegToRad();
2564  Double_t sinTh = sin(theta);
2565  Double_t xDir = sinTh*cos(phi);
2566  Double_t yDir = sinTh*sin(phi);
2567  Double_t zDir = sqrt(1.-sinTh*sinTh);
2568  x2=x1=xcoor;
2569  y2=y1=ycoor;
2570  z2=z1=0.;
2571  x2 += xDir*1000.;
2572  y2 += yDir*1000.;
2573  z2 += zDir*1000.;
2574  sizescellsMod.transFromZ0(x1,y1,z1);
2575  sizescellsMod.transFrom (x2,y2,z2);
2576  //-------------------------------------------------------
2577 
2578 
2579 
2580  //-------------------------------------------------------
2581  // find the total path length in layer
2582  Int_t firstCell,lastCell;
2583  Float_t firstCellPath,midCellPath,lastCellPath;
2584  Int_t ncells=0;
2585  if(sizescellsLay.calcCrossedCells(x1,y1,z1, x2,y2,z2,
2586  firstCell,lastCell,
2587  firstCellPath,midCellPath,lastCellPath))
2588  {
2589 
2590  ncells = 1;
2591  ncells += lastCell-firstCell;
2592 
2593  Float_t totalePathInLayer = 0.;
2594 
2595  for(Int_t cell=firstCell;cell<=lastCell;++cell) {
2596  Float_t cellPath;
2597  if (cell == firstCell) { cellPath = firstCellPath;}
2598  else if (cell == lastCell) { cellPath = lastCellPath; }
2599  else { cellPath = midCellPath; }
2600  totalePathInLayer += cellPath;
2601  }
2602 
2603  if(totalePathInLayer>Lmax) totalePathInLayer = Lmax;
2604  if(totalePathInLayer<Lmin) totalePathInLayer = Lmin;
2605 
2606  Float_t eff = effmin + ( (effmax - effmin) * (totalePathInLayer-Lmin) / (Lmax-Lmin) );
2607  //cout<<m<<" "<<l<<" theta " <<th<<" phi "<<ph <<" path " <<totalePathInLayer<<" minPath "<< Lmin <<" maxPath "<< Lmax <<" effmin "<<effmin<<" eff "<<eff<<endl;
2608  return eff;
2609 
2610  } else return 1;
2611  //-------------------------------------------------------
2612 }
2613 
2614 
void setNoiseWhiteRatio(Float_t w)
void setDTime2Err(Int_t i, Float_t timeErr)
void fillNTuple(Int_t, Int_t, Int_t, Int_t, Int_t, HMdcGeantCell *, TNtuple *)
Float_t rndmoffsets[6][4][6][220]
scaler for error of time per module type
HMdcGeantCell * fCell
pointer to noise data
Definition: hmdcdigitizer.h:98
Bool_t getNTuple()
void setSignalSpeed(Float_t speed)
static HGeantKine * getPrimary(Int_t track, HLinearCategory *cat=NULL)
Definition: hgeantkine.cc:1892
Bool_t getWireStatEffUse()
Bool_t initContainer(void)
HCategory * fCalCat
Pointer to sim data category.
Definition: hmdcdigitizer.h:84
static Float_t dTimeErr[NMAXHITS]
drift time2 + tof
static Int_t getEmbeddingRealTrackId()
Definition: hades.h:102
Definition: hevent.h:17
Float_t getTotalMomentum(void) const
Definition: hgeantkine.h:112
void setTrackList(Int_t i, Int_t track)
Definition: hmdccal1sim.h:47
Int_t cmin[6][4][6]
Definition: hmdcdigitizer.h:44
Float_t getOffset(Int_t sec, Int_t mod, Int_t lay, Int_t cell)
Definition: hmdcwirestat.h:42
void setNHitsReal(Int_t i)
void transFrom(Double_t &x, Double_t &y, Double_t &z) const
HIterator * itercell
Iterator over input category.
Float_t Lmin[6][4][6]
Definition: hmdcdigitizer.h:46
void findFirstValidHit()
void setParContainers()
Float_t getEfficiency(Int_t j) const
Definition: hmdcgeantcell.h:51
void findSecondValidHit()
Bool_t hasPrinted
map delta electron candidates to t1 offsets
Bool_t getTofUse()
void setOffsets(Float_t off0, Float_t off1, Float_t off2, Float_t off3, Int_t on_off=1)
void setScaleTime(Float_t scale)
Float_t scaleError[4]
Float_t getFractionOfmaxCharge(Int_t i)
Float_t t1minDeltaElec
0 - 1 probability to accept a delta electron (yield adjustment)
Float_t getWireOffset(Int_t j) const
Definition: hmdcgeantcell.h:50
Char_t getSector(void)
Definition: hgeantmdc.h:43
void initOffsets(TString filename="")
void setAngle(Int_t i, Float_t a)
Char_t getReadoutSide(void) const
#define NMAXHITS
Definition: hmdcdigitizer.h:36
Int_t fEventId
Iterator over cal1 category.
void setTime1(const Float_t t)
Definition: hmdccal1.h:35
static TGraph * energyLossGraph(Int_t id, Double_t hefr=0.6, TString opt="p", Bool_t exchange=kFALSE, Int_t markerstyle=8, Int_t markercolor=2, Float_t markersize=0.7)
Definition: hmdcdedx2.cc:1190
Bool_t useNoise
level of randon noise for each module type
Float_t effLayerThickness(Float_t xcoor, Float_t ycoor, Float_t th, Float_t ph, Int_t s, Int_t m, Int_t l)
layer eff object for calulation of eff depending on impact angle
Bool_t useWireStatEff
switch for use/not use wire stat container
void setDeltaElectronMinMomCut(Float_t s0=2., Float_t s1=2., Float_t s2=4.5, Float_t s3=2., Float_t s4=2., Float_t s5=4.5)
Bool_t getErrorUse()
Float_t Lmax[6][4][6]
Definition: hmdcdigitizer.h:47
Float_t fProbDeltaAccepted
beam ion (au ==109)
void setAddress(const Int_t s, const Int_t m, const Int_t l, const Int_t c)
Definition: hmdccal1.h:28
Float_t fBetaLow
dedx as function of beta for scaling
static Float_t timeOfFlight[NMAXHITS]
track numbers
void setEmbeddingMode(Int_t mode)
void setError1(const Float_t f)
Definition: hmdccal1sim.h:40
Int_t ionID
switch for use/not use momentum below momMaxDeltaElecCut for primary electrons to identify delta elec...
Bool_t offsetsCreated
switch kTRUE: create offsets,kFALSE: read from file
Bool_t cutTime2(HMdcCal1 *cal)
Definition: hmdctimecut.cc:296
Double_t getZ() const
Definition: hgeomvector.h:24
Float_t time1
setup of Mdc (sec,mod)
Float_t getDTime1(Int_t i)
Float_t getNoiseWhiteRatio()
HMdcLayerGeomPar * fDigitGeomPar
Pointer to HMdcGeantCell hit.
Definition: hmdcdigitizer.h:87
Float_t getTimeFlight(Int_t j) const
Definition: hmdcgeantcell.h:46
void fillTrackList(HMdcCal1Sim *)
void setEffLevel(Float_t eff0, Float_t eff1, Float_t eff2, Float_t eff3, Int_t on_off=1)
const Cat_t catMdcCal1
Definition: hmdcdef.h:7
Bool_t transform(Float_t, Float_t, Float_t, Float_t, Float_t, Int_t)
Bool_t calcCrossedCells(Double_t x1, Double_t y1, Double_t z1, Double_t x2, Double_t y2, Double_t z2, Float_t &cell1, Float_t &cell2) const
Double_t getWireOrient(Int_t c) const
Float_t getTime1ErrScale(Int_t m)
Definition: hmdcdigitpar.h:28
Bool_t getOffsetsUse()
Int_t getEmbeddingDebug()
Definition: hades.h:100
void resetListVariables()
Int_t getNoiseMode()
void setTime2(const Float_t t)
Definition: hmdccal1.h:36
void setNoiseWhiteWidth(Float_t w)
Float_t getScaleTime()
void getStatusList(Int_t *array)
Definition: hmdccal1sim.h:78
Float_t getTime2(void) const
Definition: hmdccal1.h:50
void setTof1(const Float_t f)
Definition: hmdccal1sim.h:42
Int_t findNonValidHit()
Bool_t modStatus(Int_t s, Int_t m) const
void setTimeCutFlags(HMdcCal1Sim *cal1)
Float_t getNoiseBandWidth()
void setTof(Int_t i, Float_t tof)
const Cat_t catMdcGeantRaw
Definition: hgeantdef.h:9
static Float_t dTime[NMAXHITS]
ration between large region and band in noise
Double_t getXinRotLay(Int_t c, Double_t xi, Double_t yi) const
void setTrackN(Int_t i, Int_t number)
void setTof2(const Float_t f)
Definition: hmdccal1sim.h:43
static Float_t angle[NMAXHITS]
tof
void setEfficiencyFlags(Int_t, Int_t, Int_t, Int_t)
Float_t getSigmaOffsets()
Float_t getDTime2(Int_t i)
HRuntimeDb * getRuntimeDb(void)
Definition: hades.h:111
HMdcDigiLayEff layEff
layer eff random numbers per track
Float_t getSignalSpeed()
Definition: hmdcdigitpar.h:32
HEvent *& getCurrentEvent(void)
Definition: hades.cc:422
const Cat_t catGeantKine
Definition: hgeantdef.h:8
void setMinimumDist(Int_t i, Float_t dist)
Int_t getGeneratorInfo() const
Definition: hgeantkine.h:127
Float_t myalpha
drift time2 error calculated by HMdcCal2ParSim
TGraph p2(xdim, pgrid, respme)
Bool_t init(void)
void setNTrack1(const Int_t n)
Definition: hmdccal1sim.h:32
virtual Int_t getModule(Int_t sector, Int_t mod)
Definition: hdetector.cc:85
Float_t yDist
Number of current event.
const Cat_t catMdcGeantCell
Definition: hmdcdef.h:9
void setAngle1(const Float_t f)
Definition: hmdccal1sim.h:36
void setSecondHit(Int_t hit2)
Float_t time2
drift time1 error calculated by HMdcCal2ParSim
Bool_t getCellEffUse()
Float_t getTime1Real()
void setFirstTime2(Float_t time2)
Int_t m2
Definition: drawAccCuts.C:11
Int_t noiseRangeLo[4]
temp array for status of noise
Float_t getLayerEfficiencyScale(Int_t s, Int_t m, Int_t l)
Definition: hmdcdigitpar.h:24
static HMdcSizesCells * getObject(void)
Float_t getOffset(Int_t i)
void setNoiseMode(Int_t mode)
void setMinDist1(const Float_t f)
Definition: hmdccal1sim.h:38
ClassImp(HDbColumn) HDbColumn
Definition: hdbcolumn.cc:18
HMdcDeDx2 * fdEdX
pointer to hmdcsizescells parameter container
Definition: hmdcdigitizer.h:94
Float_t scaleErrorMIPS[4]
scaler for error of time per module type
Int_t m1
Definition: drawAccCuts.C:11
HIterator * iterin
pointer to Container for HMdcGeantCell
Definition: hmdcdigitizer.h:99
void setNTuple(Bool_t ntuple)
Float_t getMinDist(Int_t j) const
Definition: hmdcgeantcell.h:45
Int_t getCell() const
Definition: hmdcgeantcell.h:43
Float_t getTof(Int_t i)
void fillArrays(Int_t, Int_t, Int_t, HMdcGeantCell *)
HIterator * itercal1
Iterator over cell category.
void setTofUse(Bool_t use)
Float_t getTime2Real()
void setLoopVariables(Int_t, Int_t, Int_t, Int_t, Bool_t check=kFALSE)
HCategory * fGeantCellCat
Location for new object.
Definition: hmdcdigitizer.h:83
Double_t theta
Int_t calcEfficiency(Int_t m, Float_t r, Float_t a, Float_t l)
Definition: hmdccelleff.cc:130
Int_t getID(void) const
Definition: hgeantkine.h:107
void info(Char_t level, Int_t det, const Char_t *className, const Char_t *text)
Definition: hmessagemgr.cc:473
HMdcCal1Sim * fCalnoise
pointer to data
Definition: hmdcdigitizer.h:97
Bool_t getWireOffsetUse()
Char_t getLayer(void)
Definition: hgeantmdc.h:45
static Int_t track[NMAXHITS]
minimum distance to wire
Bool_t calcCrCellsGeantMdc(Float_t &x, Float_t &y, Float_t theta, Float_t phi, Int_t &c1, Int_t &c2) const
void setSigmaOffsets(Float_t sig)
void resetMdcIter(void)
Definition: hgeantkine.h:421
void setWireStatUse(Bool_t use)
void setDTime2(Int_t i, Float_t time)
void setFirstHit(Int_t hit1)
HMdcSizesCells * fsizescells
pointer to time cut parameter container
Definition: hmdcdigitizer.h:93
Bool_t getNoiseUse()
Float_t getTime1ErrScaleMIPS(Int_t m)
Definition: hmdcdigitpar.h:30
static Float_t wireOffset[NMAXHITS]
flag for minimum distance point out of cell
Bool_t getDeDxUse()
Int_t getParentTrack(void) const
Definition: hgeantkine.h:108
HMdcDigitPar * fDigitPar
Digitisation "geom" parameters.
Definition: hmdcdigitizer.h:88
TGraph * fbetadEdx
switch for use/not use offset substraction in output
HLocation loc
HGeantKine input data.
Definition: hmdcdigitizer.h:80
Float_t getNoiseWhiteWidth()
void setHit(Float_t ax, Float_t ay, Float_t atof, Float_t ptof)
Definition: hgeantmdc.cc:63
Int_t cmax[6][4][6]
Definition: hmdcdigitizer.h:45
Float_t getLayerEfficiencyThickness(Int_t s, Int_t m, Int_t l)
Definition: hmdcdigitpar.h:26
Int_t getLayer() const
Definition: hmdcgeantcell.h:42
Int_t setup[6][4]
2 leading edges or leading and trailing edge of the signal
HSpectrometer * getSetup(void)
Definition: hades.h:112
void setWireOffset2(const Float_t f)
Definition: hmdccal1sim.h:45
void setScalerTime1Err(Float_t m0=0, Float_t m1=0, Float_t m2=0, Float_t m3=0)
Double_t getYinRotLay(Int_t c, Double_t xi, Double_t yi) const
Bool_t useDeltaMomSelection
switch for use/not use delta electron time smearing
Float_t getNoiseLevel(Int_t i)
HCategory * fGeantMdcCat
Definition: hmdcdigitizer.h:78
void setWireOffset1(const Float_t f)
Definition: hmdccal1sim.h:44
void setNTuples(void)
void fillNoiseToGeantCells(Int_t, HMdcCal1Sim *p)
void fillNoise(Int_t, Int_t, Int_t, Int_t, Int_t, Int_t, Int_t, Int_t)
Float_t getSignalSpeed()
Float_t t1maxDeltaElec
delta electron smearing lower time range for t1 [ns]
Float_t noiseLevel[4]
flag is set , if printStatus() is called
TNtuple * distance_time
file pointer for NTuple
void setEndList1(Int_t end)
TFile * myoutput
flag for use/don't use MdcTimeCut container
Bool_t useWireStatOffset
switch for use/not use eff from wire stat container (default = kTRUE)
void setError2(const Float_t f)
Definition: hmdccal1sim.h:41
Int_t ct[6][4][6]
Definition: hmdcdigitizer.h:42
void setNTrack2(const Int_t n)
Definition: hmdccal1sim.h:33
Float_t getEfficiency(Int_t i)
void setDTime1Err(Int_t i, Float_t timeErr)
static Float_t minimumdist[NMAXHITS]
error of drift time2
Hades * gHades
Definition: hades.cc:1213
#define INFO_msg(level, det, text)
Definition: hmessagemgr.h:54
HMdcCal1Sim * fCal
pointer to hmdcgeomstruct parameter container
Definition: hmdcdigitizer.h:96
Bool_t useOffsets
offsets are used to substract min tof
vector< HMdcDigiLayEff > vLayEff
simple scaler for manipulating drift times (as done by tdc slopes)
void setNoiseBandWidth(Float_t w)
Bool_t useDeDxTimeScaling
switch on/off efficiency scaling with energyloss
static Float_t fractionOfmaxCharge[NMAXHITS]
flag for efficiency
Bool_t getFlagCutEdge(Int_t j) const
Definition: hmdcgeantcell.h:49
Float_t fillTime2Noise(Int_t)
virtual Int_t getTrack(void)
Definition: hgeantmdc.h:34
Bool_t evalWireStat(Int_t, Int_t, Int_t, Int_t)
void setEfficiency(Int_t i, Float_t eff)
static Float_t dTime2Err[NMAXHITS]
error of drift time1
Bool_t getWireStatUse()
void setTimeCutUse(Bool_t use)
static Float_t theta[NMAXHITS]
efficiency of track in layer
void setNoiseRange(Int_t rangeLo0, Int_t rangeLo1, Int_t rangeLo2, Int_t rangeLo3, Int_t rangeHi0, Int_t rangeHi1, Int_t rangeHi2, Int_t rangeHi3)
void setTime2Real(Float_t t2)
Double_t getHalfPitch(void) const
HMdcCellEff * fCellEff
pointer to cal2 parameter container
Definition: hmdcdigitizer.h:90
HParSet * getContainer(const Text_t *)
Definition: hruntimedb.cc:124
static Double_t beta(Int_t id, Double_t p)
Definition: hmdcdedx2.cc:1090
HCategory * fGeantKineCat
MDC HGeant input data.
Definition: hmdcdigitizer.h:79
Float_t getAngle(Int_t i)
Char_t getModule(void)
Definition: hgeantmdc.h:44
Float_t getTime1Noise()
void setDTime1(Int_t i, Float_t time)
HMdcGeomStruct * geomstruct
pointer to MdcDeDx2 parameter container
Definition: hmdcdigitizer.h:95
void setAngle2(const Float_t f)
Definition: hmdccal1sim.h:37
Bool_t useDeltaElectrons
switch for use/not use layer thisckness eff loss
Int_t getStatus(Int_t i)
void transFromZ0(Double_t &x, Double_t &y, Double_t &z) const
Bool_t getWireStatOffsetUse()
void setWireOffsetUse(Bool_t use)
TGraph p1(xdim, pgrid, resplo)
void initVariables()
Float_t getMinimumDist(Int_t i)
void setDeltaElectronUse(Bool_t use, Bool_t useDeltaMomSel=kFALSE, Int_t ionId=109, Float_t t1min=-950., Float_t t1max=400., Float_t momCut=20., Float_t probDelta=2.)
void setStatus2(const Int_t f)
Definition: hmdccal1sim.h:35
Bool_t finalize()
Float_t getTime2Noise()
HMdcCal2ParSim * fCal2ParSim
Digitisation "phys" parameters.
Definition: hmdcdigitizer.h:89
Int_t getNHits(void) const
Definition: hmdccal1.h:48
Int_t getEmbeddingMode()
Double_t scaledTimeAboveThreshold(HGeantKine *kine=0, Double_t p=-1, Float_t t1=-999, Float_t t2=-999, Float_t *t2err=0, Int_t s=0, Int_t m=0, Int_t l=0, Int_t c=0, Double_t alpha=0, Double_t mindist=0)
Definition: hmdcdedx2.cc:1238
Float_t offsets[4]
switch for use/not use of tof in output
HMdcTimeCut * fTimeCut
pointer to wire status parameter container
Definition: hmdcdigitizer.h:92
Bool_t createoffsets
sigma of the gausian random offset distribution
Float_t effLevel[4]
switch on/off time error scaling with energyloss
HLinkedDataObject * nextMdcHit()
Definition: hgeantkine.h:380
static Float_t dTime2[NMAXHITS]
drift time1 + tof
void setOffsetsUse(Bool_t use)
Float_t calcEffval(Int_t m, Float_t r, Float_t a, Float_t l)
Definition: hmdccelleff.cc:191
void setNHits(const Int_t n)
Definition: hmdccal1.h:34
void setTdcMode(Int_t mode)
Float_t getEfficiency(Int_t sec, Int_t mod, Int_t lay, Int_t cell)
Definition: hmdcwirestat.h:41
Float_t getCellScale()
Definition: hmdcdigitpar.h:34
void setErrorUse(Bool_t use)
void setTime2Noise(Float_t time)
Float_t getDTime2Err(Int_t i)
void resetTrackList(Int_t track=-99)
Definition: hmdccal1sim.h:46
Float_t getDTime1Err(Int_t i)
Int_t arrayNoise[5]
switch for use/not use of noise generator
void setTime1Real(Float_t t1)
Bool_t testMdcSetup(Int_t s, Int_t m)
void fillNoiseLists(HMdcCal1Sim *cal1, Int_t, Int_t)
Float_t pi
Distance to the sence wire.
void setDeDxUse(Bool_t use)
void setStatus1(const Int_t f)
Definition: hmdccal1sim.h:34
void setTheta(Int_t i, Float_t th)
#define SEPERATOR_msg(sep, num)
Definition: hmessagemgr.h:63
void setCutEdge(Int_t i, Bool_t cut)
Int_t findTrack(Int_t trk)
void setCreateOffsets(Bool_t create=kTRUE)
void storeCell(Float_t, Float_t, Float_t, Int_t, Bool_t, Float_t, Float_t, Float_t)
void setNoiseUse(Bool_t use)
map< HGeantKine *, Float_t >::iterator itDelta
map delta electron candidates to t1 offsets
Bool_t cutTime1(HMdcCal1 *cal)
Definition: hmdctimecut.cc:279
Bool_t getCutEdge(Int_t i)
Float_t phi
Definition: drawAccCuts.C:15
void setWireOffset(Int_t i, Float_t off)
Float_t getCellEffLevel(Int_t i)
void getHit(Float_t &ax, Float_t &ay, Float_t &atof, Float_t &ptof)
Definition: hgeantmdc.cc:88
Int_t getTrackN(Int_t i)
void calcTime2Digitizer(Int_t, Int_t, Float_t, Float_t, Float_t *, Float_t *)
void setWireStatOffsetUse(Bool_t use)
Double_t calcWireY(Int_t cell) const
HMdcWireStat * fWireStat
pointer to cell efficiency parameter container
Definition: hmdcdigitizer.h:91
void setNoiseLevel(Float_t noise0, Float_t noise1, Float_t noise2, Float_t noise3, Int_t on_off=1)
Bool_t getTimeCutUse()
void print()
Definition: hgeantkine.cc:2011
void select(Int_t)
void setLayerThicknessEffUse(Bool_t use)
Double_t ptot
static Int_t statusflag[NMAXHITS]
impact angle in coordinate system of the cell
void setMinDist2(const Float_t f)
Definition: hmdccal1sim.h:39
Float_t fillTime1Noise(Int_t)
Float_t getSignPath(Float_t x) const
Int_t getStatus(Int_t sec, Int_t mod, Int_t lay, Int_t cell)
Definition: hmdcwirestat.h:40
void setStatus(Int_t i, Int_t stat)
const HGeomVector & getTargetMiddlePoint(void) const
Float_t getImpactAngle(Int_t j) const
Definition: hmdcgeantcell.h:47
Double_t getHalfCatDist(void) const
Int_t execute(void)
void calcTimeDigitizer(Int_t, Int_t, Float_t, Float_t, Float_t *, Float_t *)
Double_t getX() const
Definition: hgeomvector.h:22
void handleOverFlow(Int_t, Int_t, Int_t, Int_t)
Int_t getNoiseRangeLo(Int_t i)
Float_t getTheta(Int_t j) const
Definition: hmdcgeantcell.h:52
Bool_t useDeDxScaling
lower beta range for scaling
static Bool_t cutEdge[NMAXHITS]
value for fraction of maximum charge
Bool_t reinit(void)
Bool_t useLayerThickness
switch for use/not use offset from wire stat container (default = kTRUE)
Float_t momMinDeltaCut[6]
delta electron smearing : primary electrons below this mom are considdered to be delta electrons [MeV...
Int_t firstsec
end of the list of hits belonging to the first valid hit
void setTime1Noise(Float_t time)
Float_t getLayerEfficiency(Int_t s, Int_t m, Int_t l)
Definition: hmdcdigitpar.h:22
Float_t time2Error
drift time2 calculated by HMdcCal2ParSim
void setWireStatEffUse(Bool_t use)
HMdcGeantCell * hit
Pointer to cal data category.
Definition: hmdcdigitizer.h:85
void fillArraysReal(Int_t i)
Int_t getTdcMode()
Double_t getY() const
Definition: hgeomvector.h:23
HMessageMgr * getMsg(void)
Definition: hades.h:113
static Float_t efficiency[NMAXHITS]
time for signal propagation on the wire
Int_t getNTrack(Int_t j) const
Definition: hmdcgeantcell.h:48
map< HGeantKine *, Float_t > mDeltaTrackT0
min mom cut per sector (account for different mirror materials) [MeV/c]
void setStatusList(Int_t i, Int_t stat)
Definition: hmdccal1sim.h:70
HLocation locnoise
Location for new object.
Definition: hmdcdigitizer.h:81
Float_t getTime1(void) const
Definition: hmdccal1.h:49
void setCellEffUse(Bool_t use)
Float_t time1Error
drift time1 calculated by HMdcCal2ParSim
void resetStatusList(Int_t stat=0)
Definition: hmdccal1sim.h:69
Float_t getWireOffset(Int_t i)
Int_t getStatus1(void) const
Definition: hmdccal1sim.h:100
void getIncidence(Float_t &ath, Float_t &aph)
Definition: hgeantmdc.cc:96
Int_t noiseRangeHi[4]
lower range of noise for each mdc type
Bool_t useCellEff
level of requiered maximum charge to create a signal (for example 20 (=20%))
Int_t getEndList1()
Bool_t cutTimesDif(HMdcCal1 *cal)
Definition: hmdctimecut.cc:312
void setFractionOfmaxCharge(Int_t i, Float_t f)
Int_t getNoiseRangeHi(Int_t i)
Int_t m3
Definition: drawAccCuts.C:11
TGraph p3(xdim, pgrid, resphi)
Float_t momMaxDeltaElecCut
delta electron smearing upper time range for t1 [ns]