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 **************************************************************************/
18 Revision 1.1 2005/10/11 12:31:50 masera
19 Preprocessor classes for SPD (Paul Nilsson)
23 ///////////////////////////////////////////////////////////////////////////
24 // AliITSBadChannelsAuxSPD implementation by P. Nilsson 2005
25 // AUTHOR/CONTACT: Paul.Nilsson@cern.ch
27 // Auxiliary algorithms for the SPD
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.
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).
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.
44 // Examples - Converters
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;
54 // root [7] cout << c->GetRow() << endl;
56 // root [8] AliITSdigitSPD *d2 = aux->CreateDigitFromChannel(c);
57 // root [9] cout << d2->GetCoord1() << endl;
59 // root [10] cout << d2->GetCoord2() << endl;
61 // root [11] cout << d2->GetSignal() << endl;
63 // root [12] delete d2;
64 // root [13] delete d;
65 // root [14] delete c;
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.
71 // Modified by D. Elia, H. Tydesjo
72 // March 2006: Mixed up coordinates, bug fixed
74 ///////////////////////////////////////////////////////////////////////////
76 #include "AliITSBadChannelsAuxSPD.h"
78 ClassImp(AliITSBadChannelsAuxSPD)
80 //__________________________________________________________________________
81 AliITSBadChannelsAuxSPD::AliITSBadChannelsAuxSPD(void)
83 // Default constructor
86 //__________________________________________________________________________
87 Bool_t AliITSBadChannelsAuxSPD::Diff(TObjArray *&inputArray1, TObjArray *&inputArray2,
88 TObjArray *&outputArray1, TObjArray *&outputArray2) const
90 // Make a diff between the input TObjArrays
92 // Input: Two input TObjArrays of AliITSChannelSPD objects to be tested, two output TObjArrays corresponding
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
98 Bool_t status = kFALSE;
100 const Int_t kInputArray1Size = inputArray1->GetEntries();
101 const Int_t kInputArray2Size = inputArray2->GetEntries();
102 AliITSChannelSPD *ch1 = 0;
103 AliITSChannelSPD *ch2 = 0;
104 Bool_t found = kFALSE;
109 Int_t lastFoundAtJ = -1;
110 for (i = 0; i < kInputArray1Size; i++)
112 // Get the next channel from array 1
113 ch1 = (AliITSChannelSPD *) inputArray1->At(i);
115 // Is ch1 also in array 2?
116 for (j = lastFoundAtJ + 1; j < kInputArray2Size; j++)
118 ch2 = (AliITSChannelSPD *) inputArray2->At(j);
121 // Abort, go to next i
128 // If ch1 was not found in array 2, store it
131 outputArray1->Add(ch1);
141 for (i = 0; i < kInputArray2Size; i++)
143 // Get the next channel from array 2
144 ch2 = (AliITSChannelSPD *) inputArray2->At(i);
146 // Is ch2 also in array 1?
147 for (j = lastFoundAtJ + 1; j < kInputArray1Size; j++)
149 ch1 = (AliITSChannelSPD *) inputArray1->At(j);
152 // Abort, go to next i
159 // If ch1 was not found in array 1, store it
162 outputArray2->Add(ch2);
170 if (outputArray1->GetEntries() > 0 || outputArray2->GetEntries() > 0) status = kTRUE;
175 //__________________________________________________________________________
176 Bool_t AliITSBadChannelsAuxSPD::Find(AliITSChannelSPD *&channel, TObjArray *&array) const
178 // Find the channel in the array
180 // Input: AliITSChannelSPD channel object, TObjArray of AliITSChannelSPD channel objects
182 // Return: kTRUE if channel is found in the array, kFALSE otherwise
184 Bool_t status = kFALSE;
186 // Loop over all channels in the array
188 const Int_t kN = array->GetEntries();
189 while (channelNr < kN)
191 if (*channel == *(AliITSChannelSPD *)array->At(channelNr))
197 // Go to next channel
204 //__________________________________________________________________________
205 Bool_t AliITSBadChannelsAuxSPD::Find(AliITSdigitSPD *&digit, TObjArray *&array) const
207 // Find the digit in the array
209 // WARNING: Using AliITSdigitSPD digits in this way is roughly 10% slower than to use AliITSChannelSPD channels
211 // Input: AliITSdigitSPD digit object, TObjArray of AliITSChannelSPD channel objects
213 // Return: kTRUE if digit is found in the array, kFALSE otherwise
215 Bool_t status = kFALSE;
217 AliITSChannelSPD *channel = 0;
218 const Int_t kN = array->GetEntries();
220 Int_t column = digit->GetCoord1();
221 Int_t row = digit->GetCoord2();
223 // Loop over all channels in the array
224 while (channelNr < kN)
226 channel = (AliITSChannelSPD *)array->At(channelNr);
227 if ( (channel->GetColumn() == column) && (channel->GetRow() == row) )
233 // Go to next channel
240 //__________________________________________________________________________
241 AliITSdigitSPD* AliITSBadChannelsAuxSPD::CreateDigitFromChannel(const AliITSChannelSPD *&channel) const
243 // Create a digit from a channel
245 // Input: AliITSChannelSPD object
247 // Return: AliITSdigitSPD object
249 AliITSdigitSPD *digit = new AliITSdigitSPD();
251 digit->SetCoord1(channel->GetColumn());
252 digit->SetCoord2(channel->GetRow());
258 //__________________________________________________________________________
259 AliITSChannelSPD* AliITSBadChannelsAuxSPD::CreateChannelFromDigit(const AliITSdigitSPD *&digit) const
261 // Create a channel from a digit
263 // Input: AliITSdigitSPD object
265 // Return: AliITSChannelSPD object
267 AliITSChannelSPD *channel = new AliITSChannelSPD();
269 channel->SetColumn(digit->GetCoord1());
270 channel->SetRow(digit->GetCoord2());
275 //__________________________________________________________________________
276 Int_t AliITSBadChannelsAuxSPD::GetNumberOfBadChannels(Int_t* &badChannelsArray, Int_t* &indexArray, Int_t size) const
278 // Get the total number of bad channels
282 // Loop over all modules
283 for (Int_t module = 0; module < size; module++)
285 // Get the module size (i.e. the number of bad channels)
286 n += badChannelsArray[indexArray[module]];
292 //__________________________________________________________________________
293 Bool_t AliITSBadChannelsAuxSPD::CreateHTMLReport(char *name, Int_t* &badChannelsArray, Int_t* &indexArray,
294 Int_t indexArraySize, TString *buffer, Bool_t tags)
296 // Create an HTML report from the bad channels array
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
303 Bool_t status = kFALSE;
305 Int_t totalNumberOfBadChannels = 0;
306 Int_t numberOfModulesWithBadChannels = 0;
310 buffer->Append("<html>");
311 buffer->Append("<head><title>SPD bad channels</title></head>\n");
312 buffer->Append("<body>\n");
315 buffer->Append("HTML report for file: ");
316 buffer->Append(name);
318 tags ? buffer->Append("<br>\n<br>\n") : buffer->Append("\n\n");
322 // Loop over all modules
323 for (Int_t module = 0; module < indexArraySize; module++)
325 // Get the start position of the data
326 Int_t position = indexArray[module];
328 // Get the module size (i.e. the number of bad channels)
329 Int_t size = badChannelsArray[position++];
331 // Only continue if there are bad channels in this module
334 // There are bad channels in this file
336 numberOfModulesWithBadChannels++;
337 totalNumberOfBadChannels += size;
340 buffer->Append("SPD module = ");
341 snprintf(temp,9,"%d",module);
342 buffer->Append(temp);
343 buffer->Append("<br>\n");
344 buffer->Append("Number of bad channels = ");
345 snprintf(temp,9,"%d",size);
346 buffer->Append(temp);
348 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
350 buffer->Append("(column, row) = ");
352 // Get all bad channels
356 // Create and add the current channel
358 snprintf(temp,10,"%d",badChannelsArray[position++]);
359 buffer->Append(temp);
360 buffer->Append(", ");
361 snprintf(temp,10,"%d",badChannelsArray[position++]);
362 buffer->Append(temp);
367 buffer->Append(", ");
371 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
374 // Go to next bad channel
378 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
381 } // end loop over modules
385 buffer->Append("(Data does not contain any known bad channels)");
388 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
390 buffer->Append("Total number of bad channels = ");
391 snprintf(temp,10,"%d",totalNumberOfBadChannels);
392 buffer->Append(temp);
394 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
396 buffer->Append("Number of modules with bad channels = ");
397 snprintf(temp,10,"%d",numberOfModulesWithBadChannels);
398 buffer->Append(temp);
400 tags ? buffer->Append("<br>\n") : buffer->Append("\n");
402 buffer->Append("Number of modules = ");
403 snprintf(temp,10,"%d",indexArraySize);
404 buffer->Append(temp);
408 buffer->Append("<br>\n");
409 buffer->Append("</body>\n");
410 buffer->Append("</html>");
414 buffer->Append("\n");