]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RALICE/icepack/IceCleanHits.cxx
06-jun-2007 NvE Explicit tests on null pointers for returned TObjArray* from e.g...
[u/mrichter/AliRoot.git] / RALICE / icepack / IceCleanHits.cxx
CommitLineData
34d0a9fe 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
69884331 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
95f2b820 31// 4) At least one hit in another OM within radius R and time difference dt
34d0a9fe 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//
25eefd00 37// Information about the actual parameter settings can be found in the event
38// structure itself via the device named "IceCleanHits".
39//
668c6f58 40// Concerning the trigger time :
41// -----------------------------
69884331 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.
eb90778a 47// Specification of a negative trigger time will result in the automatic
69884331 48// trigger time setting corresponding to the "main" trigger.
49// By default the trigger time of the "main" trigger will be used.
668c6f58 50//
34d0a9fe 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
66ClassImp(IceCleanHits) // Class implementation to enable ROOT I/O
67
68IceCleanHits::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;
eb90778a 81 fTtimA=-1;
69884331 82 fTnamA="main";
34d0a9fe 83}
84///////////////////////////////////////////////////////////////////////////
85IceCleanHits::~IceCleanHits()
86{
87// Default destructor.
88}
89///////////////////////////////////////////////////////////////////////////
90void 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///////////////////////////////////////////////////////////////////////////
98void 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///////////////////////////////////////////////////////////////////////////
106void 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///////////////////////////////////////////////////////////////////////////
114void 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///////////////////////////////////////////////////////////////////////////
121void IceCleanHits::SetTwindowA(Float_t dtmax)
122{
69884331 123// Set Amanda maximal trigger window (in TDC counts).
34d0a9fe 124// Only hits which occur in [T-dtmax,T+dtmax] will be kept,
69884331 125// where T indicates the trigger time in TDC counts.
126// For the Amanda DAQ hardware, 1 TDC corresponds to about 1.04 ns.
34d0a9fe 127 fTwinA=dtmax;
128}
129///////////////////////////////////////////////////////////////////////////
eb90778a 130void IceCleanHits::SetTtimeA(Float_t t)
131{
69884331 132// Set Amanda trigger time (in TDC counts).
eb90778a 133// A negative value will induce automatic trigger time setting based
69884331 134// on "main" trigger as recorded in the IceEvent structure.
eb90778a 135 fTtimA=t;
69884331 136 fTnamA="user";
137 if (t<0) fTnamA="main";
138}
139///////////////////////////////////////////////////////////////////////////
140void IceCleanHits::SetTnameA(TString name)
141{
142// Set Amanda trigger name.
143// Specification of a non-existing trigger name will result in a trigger time
5b3fc586 144// value of 0.
145 fTtimA=0;
146 fTnamA=name;
eb90778a 147}
148///////////////////////////////////////////////////////////////////////////
34d0a9fe 149void 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
25eefd00 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
34d0a9fe 188 Amanda();
189 InIce();
190 IceTop();
191}
192///////////////////////////////////////////////////////////////////////////
193void IceCleanHits::Amanda()
194{
195// Hit cleaning for Amanda modules.
196
69884331 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")
eb90778a 200 {
69884331 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 }
eb90778a 207 }
668c6f58 208
34d0a9fe 209 // All Amanda OMs with a signal
210 TObjArray* aoms=fEvt->GetDevices("IceAOM");
8a394508 211 if (!aoms) return;
34d0a9fe 212
213 // Local OM array with bad/dead OMs (as indicated via IceCalibrate) discarded
214 TObjArray oms;
215 IceAOM* omx=0;
216 for (Int_t i=0; i<aoms->GetEntries(); i++)
217 {
218 omx=(IceAOM*)aoms->At(i);
219 if (!omx) continue;
220 if (omx->GetDeadValue("ADC") || omx->GetDeadValue("LE") || omx->GetDeadValue("TOT")) continue;
221 oms.Add(omx);
222 }
223
224 // Local array with clean hits
225 TObjArray hits;
226 Int_t omid=0;
227 Int_t clean=1;
228 AliSignal* sx=0;
229 Float_t adc,le,tot;
34d0a9fe 230 for (Int_t iom=0; iom<oms.GetEntries(); iom++)
231 {
232 omx=(IceAOM*)oms.At(iom);
233 if (!omx) continue;
234 omid=omx->GetUniqueID();
235 for (Int_t ih=1; ih<=omx->GetNhits(); ih++)
236 {
237 sx=omx->GetHit(ih);
238 if (!sx) continue;
239 adc=sx->GetSignal("ADC",7);
240 le=sx->GetSignal("LE",7);
241 tot=sx->GetSignal("TOT",7);
242
243 // Remove hits with an ADC value outside the range
244 if (adc<fAdcminA || adc>fAdcmaxA)
245 {
246 sx->SetDead("ADC");
247 clean=0;
248 }
249 // Remove hits with a TOT value outside the range
250 // Note : Different ranges for electrical and optical modules
251 if (omid<303) // Electrical OMs
252 {
253 if (tot<fTotminAE || tot>fTotmaxAE)
254 {
255 sx->SetDead("TOT");
256 clean=0;
257 }
258 }
259 else // Optical OMs
260 {
261 if (tot<fTotminAO || tot>fTotmaxAO)
262 {
263 sx->SetDead("TOT");
264 clean=0;
265 }
266 }
668c6f58 267 // Remove hits that are outside the trigger time window.
268 // Since the trigger time was determined from uncalibrated LE's
269 // (to include cable length effects) the uncalibrated LE of each
270 // hit should be used here as well.
271 le=sx->GetSignal("LE",-7);
eb90778a 272 if (fabs(le-fTtimA)>fTwinA)
34d0a9fe 273 {
274 sx->SetDead("LE");
275 clean=0;
276 }
34d0a9fe 277 // Store only the current clean hits in our local hit array
278 // This will save CPU time for the isolation criterion
279 if (clean) hits.Add(sx);
280 }
281 }
282
283 // Isolation cut
95f2b820 284 // Only retain hits that have at least one hit of another OM within a certain
34d0a9fe 285 // radius and within a certain time window
286 Int_t nhits=hits.GetEntries();
287 AliSignal* sx1=0;
288 AliSignal* sx2=0;
289 Float_t t1,t2;
290 IceAOM* omx1=0;
291 IceAOM* omx2=0;
292 AliPosition r1;
293 AliPosition r2;
294 Float_t dt,dr;
295 Int_t iso;
296 for (Int_t jh1=0; jh1<nhits; jh1++)
297 {
298 sx1=(AliSignal*)hits.At(jh1);
299 if (!sx1) continue;
95f2b820 300
34d0a9fe 301 iso=1;
302 for (Int_t jh2=0; jh2<nhits; jh2++)
303 {
34d0a9fe 304 sx2=(AliSignal*)hits.At(jh2);
305 if (!sx2) continue;
95f2b820 306
307 omx1=(IceAOM*)sx1->GetDevice();
308 omx2=(IceAOM*)sx2->GetDevice();
309 if (omx1==omx2) continue;
310
34d0a9fe 311 t1=sx1->GetSignal("LE",7);
312 t2=sx2->GetSignal("LE",7);
313 dt=fabs(t2-t1);
314 if (dt>fDtmaxA) continue;
95f2b820 315
34d0a9fe 316 if (omx1 && omx2)
317 {
318 r1=omx1->GetPosition();
319 r2=omx2->GetPosition();
320 dr=r1.GetDistance(r2);
321 if (dr>fRmaxA) continue;
322 iso=0;
323 }
324 }
325 if (iso) sx1->SetDead("LE");
326 }
327}
328///////////////////////////////////////////////////////////////////////////
329void IceCleanHits::InIce()
330{
331// Hit cleaning for IceCube InIce DOMs.
332}
333///////////////////////////////////////////////////////////////////////////
334void IceCleanHits::IceTop()
335{
336// Hit cleaning for IceTop DOMs.
337}
338///////////////////////////////////////////////////////////////////////////