]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RALICE/icepack/IceCleanHits.cxx
24b1238c458dfb8d281847bcacbcabbe97a8e46c
[u/mrichter/AliRoot.git] / RALICE / icepack / IceCleanHits.cxx
1 /*******************************************************************************
2  * Copyright(c) 2003, IceCube Experiment at the South Pole. All rights reserved.
3  *
4  * Author: The IceCube RALICE-based Offline Project.
5  * Contributors are mentioned in the code where appropriate.
6  *
7  * Permission to use, copy, modify and distribute this software and its
8  * documentation strictly for non-commercial purposes is hereby granted
9  * without fee, provided that the above copyright notice appears in all
10  * copies and that both the copyright notice and this permission notice
11  * appear in the supporting documentation.
12  * The authors make no claims about the suitability of this software for
13  * any purpose. It is provided "as is" without express or implied warranty.
14  *******************************************************************************/
15
16 // $Id$
17
18 ///////////////////////////////////////////////////////////////////////////
19 // Class IceCleanHits
20 // TTask derived class to perform hit cleaning.
21 //
22 // The code in this processor is based on the algorithms as developed
23 // by Oladipo Fadiran and George Japaridze (Clark Atlanta University, USA).
24 //
25 // Criteria applied for Amanda modules :
26 // -------------------------------------
27 // 1) ADC within [min,max]  Default : [0.3,999999] PE
28 // 2) TOT within [min,max]  Default : electrical [125,2000] optical [20,2000] ns
29 // 3) abs(LE-Ttrig)<=win    Default : win=2250 TDC counts
30 //    where : LE=uncalibrated hit LE (i.e. TDC counts)   Ttrig=trigger pulse LE in TDC counts
31 // 4) At least one hit in another OM within radius R and time difference dt
32 //    to remove isolated hits. Defaults : R=70 m  dt=500 ns
33 //
34 // The defaults of the various parameters can be changed by the corresponding
35 // Set memberfunctions.
36 //
37 // Information about the actual parameter settings can be found in the event
38 // structure itself via the device named "IceCleanHits".
39 //
40 // Concerning the trigger time :
41 // -----------------------------
42 // By default the trigger time is obtained automatically from the IceEvent structure
43 // via the device called "Trigger".
44 // The uncalibrated LE (i.e. TDC counts) of a specified trigger pulse is used.
45 // The user can impose a specific trigger name or time to be used
46 // by invokation of the memberfunctions SetTnameA or SetTtimeA, respectively.
47 // Specification of a negative trigger time will result in the automatic
48 // trigger time setting corresponding to the "main" trigger.
49 // By default the trigger time of the "main" trigger will be used.
50 //
51 // The hits which do not fullfill the criteria are flagged "dead" for the
52 // corresponding signal slot. This means they are still present in the
53 // IceEvent structure and are as such still accessible.
54 // It is left to the user to decide (based on the various "dead" flag settings)
55 // whether or not to use these hits in his/her reconstruction or analysis.
56 //
57 // Note : This processor only works properly on Time and ADC calibrated data.
58 //
59 //--- Author: Nick van Eijndhoven 13-oct-2005 Utrecht University
60 //- Modified: NvE $Date$ Utrecht University
61 ///////////////////////////////////////////////////////////////////////////
62  
63 #include "IceCleanHits.h"
64 #include "Riostream.h"
65
66 ClassImp(IceCleanHits) // Class implementation to enable ROOT I/O
67
68 IceCleanHits::IceCleanHits(const char* name,const char* title) : TTask(name,title)
69 {
70 // Default constructor.
71  fEvt=0;
72  fAdcminA=0.3;
73  fAdcmaxA=999999;
74  fTotminAE=125;
75  fTotmaxAE=2000;
76  fTotminAO=20;
77  fTotmaxAO=2000;
78  fRmaxA=70;
79  fDtmaxA=500;
80  fTwinA=2250;
81  fTtimA=-1;
82  fTnamA="main";
83 }
84 ///////////////////////////////////////////////////////////////////////////
85 IceCleanHits::~IceCleanHits()
86 {
87 // Default destructor.
88 }
89 ///////////////////////////////////////////////////////////////////////////
90 void IceCleanHits::SetAdcRangeA(Float_t min,Float_t max)
91 {
92 // Set Amanda ADC range in PE.
93 // The default for the maximum is 999999.
94  fAdcminA=min;
95  fAdcmaxA=max;
96 }
97 ///////////////////////////////////////////////////////////////////////////
98 void IceCleanHits::SetTotRangeAE(Float_t min,Float_t max)
99 {
100 // Set Amanda electrical TOT range in ns.
101 // The default for the maximum is 2000.
102  fTotminAE=min;
103  fTotmaxAE=max;
104 }
105 ///////////////////////////////////////////////////////////////////////////
106 void IceCleanHits::SetTotRangeAO(Float_t min,Float_t max)
107 {
108 // Set Amanda optical TOT range in ns.
109 // The default for the maximum is 2000.
110  fTotminAO=min;
111  fTotmaxAO=max;
112 }
113 ///////////////////////////////////////////////////////////////////////////
114 void IceCleanHits::SetIsolationA(Float_t rmax,Float_t dtmax)
115 {
116 // Set Amanda isolation radius (in m) and time difference (in ns).
117  fRmaxA=rmax;
118  fDtmaxA=dtmax;
119 }
120 ///////////////////////////////////////////////////////////////////////////
121 void IceCleanHits::SetTwindowA(Float_t dtmax)
122 {
123 // Set Amanda maximal trigger window (in TDC counts).
124 // Only hits which occur in [T-dtmax,T+dtmax] will be kept,
125 // where T indicates the trigger time in TDC counts.
126 // For the Amanda DAQ hardware, 1 TDC corresponds to about 1.04 ns. 
127  fTwinA=dtmax;
128 }
129 ///////////////////////////////////////////////////////////////////////////
130 void IceCleanHits::SetTtimeA(Float_t t)
131 {
132 // Set Amanda trigger time (in TDC counts).
133 // A negative value will induce automatic trigger time setting based
134 // on "main" trigger as recorded in the IceEvent structure.
135  fTtimA=t;
136  fTnamA="user";
137  if (t<0) fTnamA="main";
138 }
139 ///////////////////////////////////////////////////////////////////////////
140 void IceCleanHits::SetTnameA(TString name)
141 {
142 // Set Amanda trigger name.
143 // Specification of a non-existing trigger name will result in a trigger time
144 // value of 0.
145  fTtimA=0;
146  fTnamA=name;
147 }
148 ///////////////////////////////////////////////////////////////////////////
149 void IceCleanHits::Exec(Option_t* opt)
150 {
151 // Implementation of the hit cleaning procedures.
152
153  TString name=opt;
154  AliJob* parent=(AliJob*)(gROOT->GetListOfTasks()->FindObject(name.Data()));
155
156  if (!parent) return;
157
158  fEvt=(IceEvent*)parent->GetObject("IceEvent");
159  if (!fEvt) return;
160
161  // Storage of the used parameters in the IceCleanHits device
162  AliSignal params;
163  params.SetNameTitle("IceCleanHits","IceCleanHits processor parameters");
164  params.SetSlotName("AdcminA",1);
165  params.SetSlotName("AdcmaxA",2);
166  params.SetSlotName("TotminAE",3);
167  params.SetSlotName("TotmaxAE",4);
168  params.SetSlotName("TotminAO",5);
169  params.SetSlotName("TotmaxAO",6);
170  params.SetSlotName("RmaxA",7);
171  params.SetSlotName("DtmaxA",8);
172  params.SetSlotName("TwinA",9);
173  params.SetSlotName("TtimA",10);
174
175  params.SetSignal(fAdcminA,1);
176  params.SetSignal(fAdcmaxA,2);
177  params.SetSignal(fTotminAE,3);
178  params.SetSignal(fTotmaxAE,4);
179  params.SetSignal(fTotminAO,5);
180  params.SetSignal(fTotmaxAO,6);
181  params.SetSignal(fRmaxA,7);
182  params.SetSignal(fDtmaxA,8);
183  params.SetSignal(fTwinA,9);
184  params.SetSignal(fTtimA,10);
185
186  fEvt->AddDevice(params);
187
188  Amanda();
189  InIce();
190  IceTop();
191 }
192 ///////////////////////////////////////////////////////////////////////////
193 void IceCleanHits::Amanda()
194 {
195 // Hit cleaning for Amanda modules.
196
197  // Trigger time setting according to the user selection.
198  // By default the "main" trigger of the event will be used.
199  if (fTnamA != "user")
200  {
201   AliDevice* tdev=(AliDevice*)fEvt->GetDevice("Trigger");
202   if (tdev)
203   {
204    AliSignal* trig=tdev->GetHit(fTnamA);
205    if (trig) fTtimA=trig->GetSignal("trig_pulse_le");
206   }
207  }
208
209  // All Amanda OMs with a signal
210  TObjArray* aoms=fEvt->GetDevices("IceAOM");
211
212  // Local OM array with bad/dead OMs (as indicated via IceCalibrate) discarded
213  TObjArray oms;
214  IceAOM* omx=0;
215  for (Int_t i=0; i<aoms->GetEntries(); i++)
216  {
217   omx=(IceAOM*)aoms->At(i);
218   if (!omx) continue;
219   if (omx->GetDeadValue("ADC") || omx->GetDeadValue("LE") || omx->GetDeadValue("TOT")) continue;
220   oms.Add(omx);
221  }
222
223  // Local array with clean hits
224  TObjArray hits;
225  Int_t omid=0;
226  Int_t clean=1;
227  AliSignal* sx=0;
228  Float_t adc,le,tot;
229  for (Int_t iom=0; iom<oms.GetEntries(); iom++)
230  {
231   omx=(IceAOM*)oms.At(iom);
232   if (!omx) continue;
233   omid=omx->GetUniqueID();
234   for (Int_t ih=1; ih<=omx->GetNhits(); ih++)
235   {
236    sx=omx->GetHit(ih);
237    if (!sx) continue;
238    adc=sx->GetSignal("ADC",7);
239    le=sx->GetSignal("LE",7);
240    tot=sx->GetSignal("TOT",7);
241
242    // Remove hits with an ADC value outside the range
243    if (adc<fAdcminA || adc>fAdcmaxA)
244    {
245     sx->SetDead("ADC");
246     clean=0;
247    }
248    // Remove hits with a TOT value outside the range
249    // Note : Different ranges for electrical and optical modules
250    if (omid<303) // Electrical OMs
251    {
252     if (tot<fTotminAE || tot>fTotmaxAE)
253     {
254      sx->SetDead("TOT");
255      clean=0;
256     }
257    }
258    else // Optical OMs
259    {
260     if (tot<fTotminAO || tot>fTotmaxAO)
261     {
262      sx->SetDead("TOT");
263      clean=0;
264     }
265    }
266    // Remove hits that are outside the trigger time window.
267    // Since the trigger time was determined from uncalibrated LE's
268    // (to include cable length effects) the uncalibrated LE of each
269    // hit should be used here as well. 
270    le=sx->GetSignal("LE",-7);
271    if (fabs(le-fTtimA)>fTwinA)
272    {
273      sx->SetDead("LE");
274      clean=0;
275    }
276    // Store only the current clean hits in our local hit array
277    // This will save CPU time for the isolation criterion 
278    if (clean) hits.Add(sx);
279   }
280  }
281  
282  // Isolation cut
283  // Only retain hits that have at least one hit of another OM within a certain
284  // radius and within a certain time window
285  Int_t nhits=hits.GetEntries();
286  AliSignal* sx1=0;
287  AliSignal* sx2=0;
288  Float_t t1,t2;
289  IceAOM* omx1=0;
290  IceAOM* omx2=0;
291  AliPosition r1;
292  AliPosition r2;
293  Float_t dt,dr;
294  Int_t iso;
295  for (Int_t jh1=0; jh1<nhits; jh1++)
296  {
297   sx1=(AliSignal*)hits.At(jh1);
298   if (!sx1) continue;
299
300   iso=1;
301   for (Int_t jh2=0; jh2<nhits; jh2++)
302   {
303    sx2=(AliSignal*)hits.At(jh2);
304    if (!sx2) continue;
305
306    omx1=(IceAOM*)sx1->GetDevice();
307    omx2=(IceAOM*)sx2->GetDevice();
308    if (omx1==omx2) continue;
309
310    t1=sx1->GetSignal("LE",7);
311    t2=sx2->GetSignal("LE",7);
312    dt=fabs(t2-t1);
313    if (dt>fDtmaxA) continue;
314
315    if (omx1 && omx2)
316    {
317     r1=omx1->GetPosition();
318     r2=omx2->GetPosition();
319     dr=r1.GetDistance(r2);
320     if (dr>fRmaxA) continue;
321     iso=0;
322    }
323   }
324   if (iso) sx1->SetDead("LE");
325  }   
326 }
327 ///////////////////////////////////////////////////////////////////////////
328 void IceCleanHits::InIce()
329 {
330 // Hit cleaning for IceCube InIce DOMs.
331 }
332 ///////////////////////////////////////////////////////////////////////////
333 void IceCleanHits::IceTop()
334 {
335 // Hit cleaning for IceTop DOMs.
336 }
337 ///////////////////////////////////////////////////////////////////////////