Preprocessor classes for SPD (Paul Nilsson)
[u/mrichter/AliRoot.git] / ITS / AliITSBadChannelsAuxSPD.cxx
CommitLineData
3f0e013c 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line 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. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16/*
17$Log$
18*/
19
20///////////////////////////////////////////////////////////////////////////
21// AliITSBadChannelsAuxSPD implementation by P. Nilsson 2005
22// AUTHOR/CONTACT: Paul.Nilsson@cern.ch
23//
24// Auxiliary algorithms for the SPD
25//
26// This class contains converter methods and general algorithms for
27// handling digit <-> channel convertions and methods for identifying
28// changes (diff's) in arrays of bad channels, and for finding channels
29// or digits in arrays of bad channels.
30//
31// The Diff algorithm can be used to check if there are any changes among
32// the noisy channels. It returns two arrays, one with noisy channels
33// are no longer visible (less likely to happen) and one with newly found
34// noisy channels (more likely to happen).
35//
36// The Find algorithms looks for a given digit or channel in an array of
37// known channels. It can be used by the clustering algorithms to check
38// if a given digit that is about to be clustered, is in fact a known
39// noisy channel. It should not be used in a normal cluster.
40//
41// Examples - Converters
42//
43// root [0] AliITSdigitSPD *d = new AliITSdigitSPD();
44// root [1] d->SetCoord1(1);
45// root [2] d->SetCoord2(2);
46// root [3] d->SetSignal(1);
47// root [4] AliITSBadChannelsAuxSPD *aux = new AliITSBadChannelsAuxSPD();
48// root [5] AliITSChannelSPD *c = aux->CreateChannelFromDigit(d);
49// root [6] cout << c->GetColumn() << endl;
50// 1
51// root [7] cout << c->GetRow() << endl;
52// 2
53// root [8] AliITSdigitSPD *d2 = aux->CreateDigitFromChannel(c);
54// root [9] cout << d2->GetCoord1() << endl;
55// 1
56// root [10] cout << d2->GetCoord2() << endl;
57// 2
58// root [11] cout << d2->GetSignal() << endl;
59// 1
60// root [12] delete d2;
61// root [13] delete d;
62// root [14] delete c;
63//
64// The signal member of the digit is not a member of the channel class.
65// It is artificially introduced by the CreateDigitFromChannel method and
66// is per default set to 1.
67///////////////////////////////////////////////////////////////////////////
68
69#include "AliITSBadChannelsAuxSPD.h"
70
71ClassImp(AliITSBadChannelsAuxSPD)
72
73//__________________________________________________________________________
74AliITSBadChannelsAuxSPD::AliITSBadChannelsAuxSPD(void)
75{
76 // Default constructor
77}
78
79//__________________________________________________________________________
80Bool_t AliITSBadChannelsAuxSPD::Diff(TObjArray *&inputArray1, TObjArray *&inputArray2,
81 TObjArray *&outputArray1, TObjArray *&outputArray2) const
82{
83 // Make a diff between the input TObjArrays
84 //
85 // Input: Two input TObjArrays of AliITSChannelSPD objects to be tested, two output TObjArrays corresponding
86 // to
87 // Output: Two output TObjArrays where outputArray1 contains the AliITSChannelSPD objects from inputArray1
88 // that are not in inputArray2, vice versa for outputArray2.
89 // Return: kTRUE if the arrays differ
90
91 Bool_t status = kFALSE;
92
93 const Int_t kInputArray1Size = inputArray1->GetEntries();
94 const Int_t kInputArray2Size = inputArray2->GetEntries();
95 AliITSChannelSPD *ch1 = 0;
96 AliITSChannelSPD *ch2 = 0;
97 Bool_t found = kFALSE;
98
99 Int_t i = 0, j = 0;
100
101 // Pass 1
102 Int_t lastFoundAtJ = -1;
103 for (i = 0; i < kInputArray1Size; i++)
104 {
105 // Get the next channel from array 1
106 ch1 = (AliITSChannelSPD *) inputArray1->At(i);
107
108 // Is ch1 also in array 2?
109 for (j = lastFoundAtJ + 1; j < kInputArray2Size; j++)
110 {
111 ch2 = (AliITSChannelSPD *) inputArray2->At(j);
112 if (*ch1 == *ch2)
113 {
114 // Abort, go to next i
115 found = kTRUE;
116 lastFoundAtJ = j;
117 break;
118 }
119 }
120
121 // If ch1 was not found in array 2, store it
122 if (!found)
123 {
124 outputArray1->Add(ch1);
125 }
126 else
127 {
128 found = kFALSE;
129 }
130 }
131
132 // Pass 2
133 lastFoundAtJ = -1;
134 for (i = 0; i < kInputArray2Size; i++)
135 {
136 // Get the next channel from array 2
137 ch2 = (AliITSChannelSPD *) inputArray2->At(i);
138
139 // Is ch2 also in array 1?
140 for (j = lastFoundAtJ + 1; j < kInputArray1Size; j++)
141 {
142 ch1 = (AliITSChannelSPD *) inputArray1->At(j);
143 if (*ch1 == *ch2)
144 {
145 // Abort, go to next i
146 found = kTRUE;
147 lastFoundAtJ = j;
148 break;
149 }
150 }
151
152 // If ch1 was not found in array 1, store it
153 if (!found)
154 {
155 outputArray2->Add(ch2);
156 }
157 else
158 {
159 found = kFALSE;
160 }
161 }
162
163 if (outputArray1->GetEntries() > 0 || outputArray2->GetEntries() > 0) status = kTRUE;
164
165 return status;
166}
167
168//__________________________________________________________________________
169Bool_t AliITSBadChannelsAuxSPD::Find(AliITSChannelSPD *&channel, TObjArray *&array) const
170{
171 // Find the channel in the array
172 //
173 // Input: AliITSChannelSPD channel object, TObjArray of AliITSChannelSPD channel objects
174 // Ouput: (none)
175 // Return: kTRUE if channel is found in the array, kFALSE otherwise
176
177 Bool_t status = kFALSE;
178
179 // Loop over all channels in the array
180 Int_t channelNr = 0;
181 const Int_t kN = array->GetEntries();
182 while (channelNr < kN)
183 {
184 if (*channel == *(AliITSChannelSPD *)array->At(channelNr))
185 {
186 status = kTRUE;
187 break;
188 }
189
190 // Go to next channel
191 channelNr++;
192 }
193
194 return status;
195}
196
197//__________________________________________________________________________
198Bool_t AliITSBadChannelsAuxSPD::Find(AliITSdigitSPD *&digit, TObjArray *&array) const
199{
200 // Find the digit in the array
201 //
202 // WARNING: Using AliITSdigitSPD digits in this way is roughly 10% slower than to use AliITSChannelSPD channels
203 //
204 // Input: AliITSdigitSPD digit object, TObjArray of AliITSChannelSPD channel objects
205 // Ouput: (none)
206 // Return: kTRUE if digit is found in the array, kFALSE otherwise
207
208 Bool_t status = kFALSE;
209
210 AliITSChannelSPD *channel = 0;
211 const Int_t kN = array->GetEntries();
212 Int_t channelNr = 0;
213 Int_t column = digit->GetCoord1();
214 Int_t row = digit->GetCoord1();
215
216 // Loop over all channels in the array
217 while (channelNr < kN)
218 {
219 channel = (AliITSChannelSPD *)array->At(channelNr);
220 if ( (channel->GetColumn() == column) && (channel->GetRow() == row) )
221 {
222 status = kTRUE;
223 break;
224 }
225
226 // Go to next channel
227 channelNr++;
228 }
229
230 return status;
231}
232
233//__________________________________________________________________________
234AliITSdigitSPD* AliITSBadChannelsAuxSPD::CreateDigitFromChannel(const AliITSChannelSPD *&channel) const
235{
236 // Create a digit from a channel
237 //
238 // Input: AliITSChannelSPD object
239 // Ouput: (none)
240 // Return: AliITSdigitSPD object
241
242 AliITSdigitSPD *digit = new AliITSdigitSPD();
243
244 digit->SetCoord1(channel->GetColumn());
245 digit->SetCoord2(channel->GetRow());
246 digit->SetSignal(1);
247
248 return digit;
249}
250
251//__________________________________________________________________________
252AliITSChannelSPD* AliITSBadChannelsAuxSPD::CreateChannelFromDigit(const AliITSdigitSPD *&digit) const
253{
254 // Create a channel from a digit
255 //
256 // Input: AliITSdigitSPD object
257 // Ouput: (none)
258 // Return: AliITSChannelSPD object
259
260 AliITSChannelSPD *channel = new AliITSChannelSPD();
261
262 channel->SetColumn(digit->GetCoord1());
263 channel->SetRow(digit->GetCoord2());
264
265 return channel;
266}
267
268//__________________________________________________________________________
269Int_t AliITSBadChannelsAuxSPD::GetNumberOfBadChannels(Int_t* &badChannelsArray, Int_t* &indexArray, Int_t size) const
270{
271 // Get the total number of bad channels
272
273 Int_t n = 0;
274
275 // Loop over all modules
276 for (Int_t module = 0; module < size; module++)
277 {
278 // Get the module size (i.e. the number of bad channels)
279 n += badChannelsArray[indexArray[module]];
280 }
281
282 return n;
283}
284
285//__________________________________________________________________________
286Bool_t AliITSBadChannelsAuxSPD::CreateHTMLReport(char *name, Int_t* &badChannelsArray, Int_t* &indexArray,
287 const Int_t indexArraySize, TString *buffer, Bool_t tags)
288{
289 // Create an HTML report from the bad channels array
290 //
291 // Input : file name, badChannelsArray, indexArray, size of indexArray (i.e. number of modules),
292 // tags boolean (if true, html tags will be added; if false, only formatted text will be created)
293 // Output: TString (buffer) containing the html code/ASCII text
294 // Return: kTRUE if a report has been created
295
296 Bool_t status = kFALSE;
297
298 Int_t totalNumberOfBadChannels = 0;
299 Int_t numberOfModulesWithBadChannels = 0;
300
301 if (tags)
302 {
303 buffer->Append("<html>");
304 buffer->Append("<head><title>SPD bad channels</title></head>\n");
305 buffer->Append("<body>\n");
306 }
307
308 buffer->Append("HTML report for file: ");
309 buffer->Append(name);
310
311 tags ? buffer->Append("<br>\n<br>\n") : buffer->Append("\n\n");
312
313 char temp[10];
314
315 // Loop over all modules
316 for (Int_t module = 0; module < indexArraySize; module++)
317 {
318 // Get the start position of the data
319 Int_t position = indexArray[module];
320
321 // Get the module size (i.e. the number of bad channels)
322 Int_t size = badChannelsArray[position++];
323
324 // Only continue if there are bad channels in this module
325 if (size > 0)
326 {
327 // There are bad channels in this file
328 status = kTRUE;
329 numberOfModulesWithBadChannels++;
330 totalNumberOfBadChannels += size;
331
332 // Create report
333 buffer->Append("SPD module = ");
334 sprintf(temp,"%d",module);
335 buffer->Append(temp);
336 buffer->Append("<br>\n");
337 buffer->Append("Number of bad channels = ");
338 sprintf(temp,"%d",size);
339 buffer->Append(temp);
340
341 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
342
343 buffer->Append("(column, row) = ");
344
345 // Get all bad channels
346 Int_t i = 0;
347 while (i < size)
348 {
349 // Create and add the current channel
350 buffer->Append("(");
351 sprintf(temp,"%d",badChannelsArray[position++]);
352 buffer->Append(temp);
353 buffer->Append(", ");
354 sprintf(temp,"%d",badChannelsArray[position++]);
355 buffer->Append(temp);
356 buffer->Append(")");
357
358 if (i < size - 1)
359 {
360 buffer->Append(", ");
361 }
362 else
363 {
364 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
365 }
366
367 // Go to next bad channel
368 i++;
369 }
370
371 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
372
373 } // if size > 0
374 } // end loop over modules
375
376 if (!status)
377 {
378 buffer->Append("(Data does not contain any known bad channels)");
379 }
380
381 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
382
383 buffer->Append("Total number of bad channels = ");
384 sprintf(temp,"%d",totalNumberOfBadChannels);
385 buffer->Append(temp);
386
387 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
388
389 buffer->Append("Number of modules with bad channels = ");
390 sprintf(temp,"%d",numberOfModulesWithBadChannels);
391 buffer->Append(temp);
392
393 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
394
395 buffer->Append("Number of modules = ");
396 sprintf(temp,"%d",indexArraySize);
397 buffer->Append(temp);
398
399 if (tags)
400 {
401 buffer->Append("<br>\n");
402 buffer->Append("</body>\n");
403 buffer->Append("</html>");
404 }
405 else
406 {
407 buffer->Append("\n");
408 }
409
410 return status;
411}