1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
20 ///////////////////////////////////////////////////////////////////////////
21 // AliITSBadChannelsAuxSPD implementation by P. Nilsson 2005
22 // AUTHOR/CONTACT: Paul.Nilsson@cern.ch
24 // Auxiliary algorithms for the SPD
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.
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).
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.
41 // Examples - Converters
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;
51 // root [7] cout << c->GetRow() << endl;
53 // root [8] AliITSdigitSPD *d2 = aux->CreateDigitFromChannel(c);
54 // root [9] cout << d2->GetCoord1() << endl;
56 // root [10] cout << d2->GetCoord2() << endl;
58 // root [11] cout << d2->GetSignal() << endl;
60 // root [12] delete d2;
61 // root [13] delete d;
62 // root [14] delete c;
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 ///////////////////////////////////////////////////////////////////////////
69 #include "AliITSBadChannelsAuxSPD.h"
71 ClassImp(AliITSBadChannelsAuxSPD)
73 //__________________________________________________________________________
74 AliITSBadChannelsAuxSPD::AliITSBadChannelsAuxSPD(void)
76 // Default constructor
79 //__________________________________________________________________________
80 Bool_t AliITSBadChannelsAuxSPD::Diff(TObjArray *&inputArray1, TObjArray *&inputArray2,
81 TObjArray *&outputArray1, TObjArray *&outputArray2) const
83 // Make a diff between the input TObjArrays
85 // Input: Two input TObjArrays of AliITSChannelSPD objects to be tested, two output TObjArrays corresponding
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
91 Bool_t status = kFALSE;
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;
102 Int_t lastFoundAtJ = -1;
103 for (i = 0; i < kInputArray1Size; i++)
105 // Get the next channel from array 1
106 ch1 = (AliITSChannelSPD *) inputArray1->At(i);
108 // Is ch1 also in array 2?
109 for (j = lastFoundAtJ + 1; j < kInputArray2Size; j++)
111 ch2 = (AliITSChannelSPD *) inputArray2->At(j);
114 // Abort, go to next i
121 // If ch1 was not found in array 2, store it
124 outputArray1->Add(ch1);
134 for (i = 0; i < kInputArray2Size; i++)
136 // Get the next channel from array 2
137 ch2 = (AliITSChannelSPD *) inputArray2->At(i);
139 // Is ch2 also in array 1?
140 for (j = lastFoundAtJ + 1; j < kInputArray1Size; j++)
142 ch1 = (AliITSChannelSPD *) inputArray1->At(j);
145 // Abort, go to next i
152 // If ch1 was not found in array 1, store it
155 outputArray2->Add(ch2);
163 if (outputArray1->GetEntries() > 0 || outputArray2->GetEntries() > 0) status = kTRUE;
168 //__________________________________________________________________________
169 Bool_t AliITSBadChannelsAuxSPD::Find(AliITSChannelSPD *&channel, TObjArray *&array) const
171 // Find the channel in the array
173 // Input: AliITSChannelSPD channel object, TObjArray of AliITSChannelSPD channel objects
175 // Return: kTRUE if channel is found in the array, kFALSE otherwise
177 Bool_t status = kFALSE;
179 // Loop over all channels in the array
181 const Int_t kN = array->GetEntries();
182 while (channelNr < kN)
184 if (*channel == *(AliITSChannelSPD *)array->At(channelNr))
190 // Go to next channel
197 //__________________________________________________________________________
198 Bool_t AliITSBadChannelsAuxSPD::Find(AliITSdigitSPD *&digit, TObjArray *&array) const
200 // Find the digit in the array
202 // WARNING: Using AliITSdigitSPD digits in this way is roughly 10% slower than to use AliITSChannelSPD channels
204 // Input: AliITSdigitSPD digit object, TObjArray of AliITSChannelSPD channel objects
206 // Return: kTRUE if digit is found in the array, kFALSE otherwise
208 Bool_t status = kFALSE;
210 AliITSChannelSPD *channel = 0;
211 const Int_t kN = array->GetEntries();
213 Int_t column = digit->GetCoord1();
214 Int_t row = digit->GetCoord1();
216 // Loop over all channels in the array
217 while (channelNr < kN)
219 channel = (AliITSChannelSPD *)array->At(channelNr);
220 if ( (channel->GetColumn() == column) && (channel->GetRow() == row) )
226 // Go to next channel
233 //__________________________________________________________________________
234 AliITSdigitSPD* AliITSBadChannelsAuxSPD::CreateDigitFromChannel(const AliITSChannelSPD *&channel) const
236 // Create a digit from a channel
238 // Input: AliITSChannelSPD object
240 // Return: AliITSdigitSPD object
242 AliITSdigitSPD *digit = new AliITSdigitSPD();
244 digit->SetCoord1(channel->GetColumn());
245 digit->SetCoord2(channel->GetRow());
251 //__________________________________________________________________________
252 AliITSChannelSPD* AliITSBadChannelsAuxSPD::CreateChannelFromDigit(const AliITSdigitSPD *&digit) const
254 // Create a channel from a digit
256 // Input: AliITSdigitSPD object
258 // Return: AliITSChannelSPD object
260 AliITSChannelSPD *channel = new AliITSChannelSPD();
262 channel->SetColumn(digit->GetCoord1());
263 channel->SetRow(digit->GetCoord2());
268 //__________________________________________________________________________
269 Int_t AliITSBadChannelsAuxSPD::GetNumberOfBadChannels(Int_t* &badChannelsArray, Int_t* &indexArray, Int_t size) const
271 // Get the total number of bad channels
275 // Loop over all modules
276 for (Int_t module = 0; module < size; module++)
278 // Get the module size (i.e. the number of bad channels)
279 n += badChannelsArray[indexArray[module]];
285 //__________________________________________________________________________
286 Bool_t AliITSBadChannelsAuxSPD::CreateHTMLReport(char *name, Int_t* &badChannelsArray, Int_t* &indexArray,
287 const Int_t indexArraySize, TString *buffer, Bool_t tags)
289 // Create an HTML report from the bad channels array
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
296 Bool_t status = kFALSE;
298 Int_t totalNumberOfBadChannels = 0;
299 Int_t numberOfModulesWithBadChannels = 0;
303 buffer->Append("<html>");
304 buffer->Append("<head><title>SPD bad channels</title></head>\n");
305 buffer->Append("<body>\n");
308 buffer->Append("HTML report for file: ");
309 buffer->Append(name);
311 tags ? buffer->Append("<br>\n<br>\n") : buffer->Append("\n\n");
315 // Loop over all modules
316 for (Int_t module = 0; module < indexArraySize; module++)
318 // Get the start position of the data
319 Int_t position = indexArray[module];
321 // Get the module size (i.e. the number of bad channels)
322 Int_t size = badChannelsArray[position++];
324 // Only continue if there are bad channels in this module
327 // There are bad channels in this file
329 numberOfModulesWithBadChannels++;
330 totalNumberOfBadChannels += size;
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);
341 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
343 buffer->Append("(column, row) = ");
345 // Get all bad channels
349 // Create and add the current channel
351 sprintf(temp,"%d",badChannelsArray[position++]);
352 buffer->Append(temp);
353 buffer->Append(", ");
354 sprintf(temp,"%d",badChannelsArray[position++]);
355 buffer->Append(temp);
360 buffer->Append(", ");
364 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
367 // Go to next bad channel
371 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
374 } // end loop over modules
378 buffer->Append("(Data does not contain any known bad channels)");
381 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
383 buffer->Append("Total number of bad channels = ");
384 sprintf(temp,"%d",totalNumberOfBadChannels);
385 buffer->Append(temp);
387 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
389 buffer->Append("Number of modules with bad channels = ");
390 sprintf(temp,"%d",numberOfModulesWithBadChannels);
391 buffer->Append(temp);
393 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
395 buffer->Append("Number of modules = ");
396 sprintf(temp,"%d",indexArraySize);
397 buffer->Append(temp);
401 buffer->Append("<br>\n");
402 buffer->Append("</body>\n");
403 buffer->Append("</html>");
407 buffer->Append("\n");