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