1 /**************************************************************************
2 * Copyright(c) 2007-2009, 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 ///////////////////////////////////////////////////////////////////
19 // Implementation of the class for SDD DCS data analysis //
20 // Origin: F.Prino, Torino, prino@to.infn.it //
21 // V.Pospisil, CTU Prague, gdermog@seznam.cz //
22 ///////////////////////////////////////////////////////////////////
25 #include "AliITSDCSAnalyzerSDD.h"
26 #include "AliDCSValue.h"
28 #include "AliITSgeomTGeo.h"
30 ClassImp(AliITSDCSAnalyzerSDD)
32 //---------------------------------------------------------------
33 AliITSDCSAnalyzerSDD::AliITSDCSAnalyzerSDD(): TObject(),
34 fHVDelay(0),fMVDelay(0),fTLDelay(0),fTRDelay(0),fStTLDelay(0),fStTRDelay(0),fOKDelay(0),
35 fHVThresholdFrac(0), fMVThresholdFrac(0), fTLThresholdFrac(0), fTRThresholdFrac(0)
37 // Default constructor
43 for( Int_t moduleLoop = 0; moduleLoop < kNmodules; moduleLoop++ ) fDCSData[moduleLoop] = NULL;
44 } /*AliITSDCSAnalyzerSDD::AliITSDCSAnalyzerSDD*/
46 //---------------------------------------------------------------
48 AliITSDCSAnalyzerSDD::AliITSDCSAnalyzerSDD(const AliITSDCSAnalyzerSDD& /* dcsa */): TObject(),
49 fHVDelay(0),fMVDelay(0),fTLDelay(0),fTRDelay(0),fStTLDelay(0),fStTRDelay(0),fOKDelay(0),
50 fHVThresholdFrac(0), fMVThresholdFrac(0), fTLThresholdFrac(0), fTRThresholdFrac(0)
53 // Copies are not allowed. The method is protected to avoid misuse.
54 AliError("Copy constructor not allowed");
55 } /*AliITSDCSAnalyzerSDD::AliITSDCSAnalyzerSDD*/
57 //---------------------------------------------------------------
59 AliITSDCSAnalyzerSDD& AliITSDCSAnalyzerSDD::operator=(const AliITSDCSAnalyzerSDD& /* dcsa */)
62 // Assignment is not allowed. The method is protected to avoid misuse.
63 AliError("Assignment operator not allowed");
65 }/*AliITSDCSAnalyzerSDD::operator=*/
67 //---------------------------------------------------------------
69 AliITSDCSAnalyzerSDD::~AliITSDCSAnalyzerSDD()
72 for(int j=0; j<kNmodules; j++)
74 if( fDCSData[j] ) delete fDCSData[j];
76 } /*AliITSDCSAnalyzerSDD::~AliITSDCSAnalyzerSDD*/
78 //---------------------------------------------------------------
80 void AliITSDCSAnalyzerSDD::AnalyzeData(TMap* dcsMap)
82 // Data processing. Takes DCS points from alias map and sorts them into AliITSDCSDataSDD objects.
84 Int_t counter = 0; // Counter of stored DCS records
86 Float_t lastTLValUpper;
87 Float_t lastTLValLower;
88 Float_t lastTRValUpper;
89 Float_t lastTRValLower;
90 Float_t lastHVValUpper;
91 Float_t lastHVValLower;
92 Float_t lastMVValUpper;
93 Float_t lastMVValLower;
94 // Thresholds for float DCS variables
96 Int_t nEntries; // Number of entries in each TObjArray, that contains DCS variable values
97 AliDCSValue *valToProcess;
98 // Pointer to currently processed DCS variable value
99 Float_t valToProcessFloat;
100 // Value of currently processed DCS variable
103 for( Int_t iLay = 3; iLay < 5; iLay++ )
106 Int_t maxLad = ( iLay == 3) ? kNladders3 : kNladders4;
107 Int_t maxMod = ( iLay == 3) ? kNmodLad3 : kNmodLad4;
109 for(Int_t iLad = 0; iLad < maxLad; iLad++)
111 for(Int_t iMod = 0; iMod < maxMod; iMod++)
113 // Loads arrays of DCS variables from map. Variables are
114 // searched by names (for ex. SDD_LAYER3_LADDER5_MODULE4_HV)
116 Int_t moduleLoop = AliITSgeomTGeo::GetModuleIndex( iLay, iLad + 1, iMod + 1 ) - 240;
118 fDCSData[moduleLoop] = new AliITSDCSDataSDD();
119 // DCS data for specific SDD module will be stored in this class
121 TObjArray* arrHV = (TObjArray*) dcsMap->GetValue( fHVDPNames[moduleLoop].Data() );
122 if(!arrHV) // There is no record for high voltage in the map
124 AliWarning( Form("DCS HV alias %s not found!\n", fHVDPNames[moduleLoop].Data()) );
128 TObjArray* arrMV = (TObjArray*) dcsMap->GetValue( fMVDPNames[moduleLoop].Data() );
129 if(!arrMV) // There is no record for medium voltage in the map
131 AliWarning( Form("DCS MV alias %s not found!\n", fMVDPNames[moduleLoop].Data()));
135 TObjArray* arrOK = (TObjArray*) dcsMap->GetValue( fOKDPNames[moduleLoop].Data() );
136 if(!arrOK) // There is no record for OK status in the map
138 AliWarning( Form("DCS MOD_OK alias %s not found!\n", fOKDPNames[moduleLoop].Data()));
142 TObjArray* arrTL = (TObjArray*) dcsMap->GetValue( fTLDPNames[moduleLoop].Data() );
143 if(!arrTL) // There is no record for temperature on left side in the map
145 AliWarning( Form("DCS TEMP_L alias %s not found!\n", fTLDPNames[moduleLoop].Data()));
149 TObjArray* arrTR = (TObjArray*) dcsMap->GetValue( fTRDPNames[moduleLoop].Data() );
150 if(!arrTR) // There is no record for temperature on right side in the map
152 AliWarning( Form("DCS TEMP_R alias %s not found!\n", fTRDPNames[moduleLoop].Data()));
156 TObjArray* arrStTL = (TObjArray*) dcsMap->GetValue( fTLStDPNames[moduleLoop].Data() );
157 if(!arrStTL) // There is no record for TEMP_L status in the map
159 AliWarning( Form("DCS TEMP_L_STATE alias %s not found!\n", fTLStDPNames[moduleLoop].Data()));
163 TObjArray* arrStTR = (TObjArray*) dcsMap->GetValue( fTRStDPNames[moduleLoop].Data() );
164 if(!arrStTR) // There is no record for TEMP_R status in the map
166 AliWarning( Form("DCS TEMP_R_STATE alias %s not found!\n", fTRStDPNames[moduleLoop].Data()));
171 lastTLValUpper = -1e-10;
172 lastTLValLower = +1e+10;
173 lastTRValUpper = -1e-10;
174 lastTRValLower = +1e+10;
175 lastHVValUpper = -1e-10;
176 lastHVValLower = +1e+10;
177 lastMVValUpper = -1e-10;
178 lastMVValLower = +1e+10;
179 // First value of any DCS variable must be written
181 nEntries = arrTL->GetEntries();
182 fDCSData[moduleLoop]->SetNPointsTempLeft( nEntries );
183 // Left temperature array size is set
185 for( Int_t tlLoop = 0; tlLoop < nEntries; tlLoop++ )
186 { // Left temerature values are copied into the AliITSDCSDataSDD TempLeft array
187 valToProcess = (AliDCSValue *)(arrTL->At(tlLoop));
188 valToProcessFloat = valToProcess->GetFloat();
189 // Value is readed from the input array
191 // /**//**/if( moduleLoop == 259 )
192 // /**//**/fprintf( stderr, " lastTLValLower = %f, valToProcessFloat = %f, lastTLValUpper = %f, fTLThresholdFrac = %f\n",
193 // /**//**/ lastTLValLower, valToProcessFloat, lastTLValUpper, fTLThresholdFrac );
195 if( lastTLValLower <= valToProcessFloat && valToProcessFloat <= lastTLValUpper ) continue;
196 // Value did not cross the treshold (upper neither lower),
197 // it is not necessary to store it.
198 fDCSData[moduleLoop]->SetValueTempLeft( valToProcess->GetTimeStamp() - fTLDelay, valToProcessFloat );
200 lastTLValLower = valToProcessFloat * ( 1.0 - fTLThresholdFrac );
201 lastTLValUpper = valToProcessFloat * ( 1.0 + fTLThresholdFrac );
202 // New tresholds are set
208 nEntries = arrTR->GetEntries();
209 fDCSData[moduleLoop]->SetNPointsTempRight( nEntries );
210 // Right temperature array size is set
212 for( Int_t trLoop = 0; trLoop < nEntries; trLoop++ )
213 { // Right temerature values are copied into the AliITSDCSDataSDD TempRight array
214 valToProcess = (AliDCSValue *)(arrTR->At(trLoop));
215 valToProcessFloat = valToProcess->GetFloat();
216 // Value is readed from the input array
218 if( lastTRValLower <= valToProcessFloat && valToProcessFloat <= lastTRValUpper ) continue;
219 // Value did not cross the treshold (upper neither lower),
220 // it is not necessary to store it.
221 fDCSData[moduleLoop]->SetValueTempRight( valToProcess->GetTimeStamp() - fTRDelay, valToProcessFloat );
223 lastTRValLower = valToProcessFloat * ( 1.0 - fTRThresholdFrac );
224 lastTRValUpper = valToProcessFloat * ( 1.0 + fTRThresholdFrac );
225 // New tresholds are set
231 nEntries = arrHV->GetEntries();
232 fDCSData[moduleLoop]->SetNPointsHV( nEntries );
233 // HV array size is set
235 for( Int_t hvLoop = 0; hvLoop < nEntries; hvLoop++ )
236 { // HV values are copied into the AliITSDCSDataSDD HV array
237 valToProcess = (AliDCSValue *)(arrHV->At(hvLoop));
238 valToProcessFloat = valToProcess->GetFloat();
239 // Value is readed from the input array
240 if( lastHVValLower <= valToProcessFloat && valToProcessFloat <= lastHVValUpper ) continue;
241 // Value did not cross the treshold (upper neither lower),
242 // it is not necessary to store it.
243 fDCSData[moduleLoop]->SetValueHV( valToProcess->GetTimeStamp() - fHVDelay, valToProcessFloat );
245 lastHVValLower = valToProcessFloat * ( 1.0 - fHVThresholdFrac );
246 lastHVValUpper = valToProcessFloat * ( 1.0 + fHVThresholdFrac );
247 // New tresholds are set
253 nEntries = arrMV->GetEntries();
254 fDCSData[moduleLoop]->SetNPointsMV( nEntries );
255 // MV array size is set
257 for( Int_t mvLoop = 0; mvLoop < nEntries; mvLoop++ )
258 { // MV values are copied into the AliITSDCSDataSDD MV array
259 valToProcess = (AliDCSValue *)(arrMV->At(mvLoop));
260 valToProcessFloat = valToProcess->GetFloat();
261 // Value is readed from the input array
262 if( lastMVValLower <= valToProcessFloat && valToProcessFloat <= lastMVValUpper ) continue;
263 // Value did not cross the treshold (upper neither lower),
264 // it is not necessary to store it.
265 fDCSData[moduleLoop]->SetValueMV( valToProcess->GetTimeStamp() - fMVDelay, valToProcessFloat );
267 lastMVValLower = valToProcessFloat * ( 1.0 - fMVThresholdFrac );
268 lastMVValUpper = valToProcessFloat * ( 1.0 + fMVThresholdFrac );
269 // New treshold is ser
274 /* Following part of the code is responsibile for the condensing of all status information given by DCS
275 into one array of Char_t. Each record of this array is in principle a bit map :
278 1. bit ... _TEMP_L_STATE
279 2. bit ... _TEMP_R_STATE
281 Each record have its own time stamp. Because there are three inputs with independent time stamp,
282 some algorithm which assigns new time stamp to bitmap according to three input time stamps is
285 Let's vizualize time stamps of the three input arrays. There is time on x-axis :
287 +------------+---------------------+------
289 +-----++------+----+--------+------------+------
290 | | | | | _TEMP_L_STATE
291 +--+------+---+--+-------+-----+--------+---+------
292 | | | | | | _TEMP_R_STATE
293 +-------------+----------+-----+--------+---+------
295 | | | | | | | | | | |
296 V V V V V V V V V V V
298 +---+----+-+--+---+---+--+-----+--------+---+------
299 | | | | | | | | | | | Status bitmap
300 +---+----+-+--+---+---+--+-----+--------+---+------
303 Principle of combining three status records into one is visible from the picture.
304 If there are two sequent records with the same status bitmap, they are joined into
305 one (with the time stamp of the earliest one).
309 Int_t nStTLEntries = arrStTL->GetEntries();
310 Int_t nStTREntries = arrStTR->GetEntries();
311 Int_t nOKEntries = arrOK->GetEntries();
312 // Gets number of _STAT_L, _STAT_R and _OK values stored in dcsMap
314 if( nStTLEntries < 1 )
315 { // TObjArray arrStTL is empty. This would cause segmentation violation during
316 // the condensing, so this case must be handled before algorithm starts
317 AliWarning( Form( "%s contains no data!\n", fTLStDPNames[moduleLoop].Data() ) );
319 arrStTL->Add( new AliDCSValue( (Int_t)0, 0x7FFFFFFF ) );
320 // 0x7FFFFFFF = 2147483647, maximal signed Int_t number. Left temperature
321 // sensor will be regarded as switched-off during whole run.
324 if( nStTREntries < 1 )
325 { // TObjArray arrStTR is empty. This would cause segmentation violation during
326 // the condensing, so this case must be handled before algorithm starts
327 AliWarning( Form( "%s contains no data!\n", fTRStDPNames[moduleLoop].Data() ) );
329 arrStTR->Add( new AliDCSValue( (Int_t)0, 0x7FFFFFFF ) );
330 // 0x7FFFFFFF = 2147483647, maximal signed Int_t number. Right temperature
331 // sensor will be regarded as switched-off during whole run.
335 { // TObjArray arrOK is empty. This would cause segmentation violation during
336 // the condensing, so this case must be handled before algorithm starts
337 AliWarning( Form( "%s contains no data!\n", fOKDPNames[moduleLoop].Data() ) );
339 arrOK->Add( new AliDCSValue( (Bool_t)0, 0x7FFFFFFF ) );
340 // 0x7FFFFFFF = 2147483647, maximal signed Int_t number.
341 // Module will be regarded as switched-off during whole run.
347 // Condensing would work properly only in the case that
348 // the input arrays are sorted by time
350 Int_t nEntriesMax = nStTLEntries + nStTREntries + nOKEntries;
351 fDCSData[moduleLoop]->SetNPointsStatus( nEntriesMax );
352 // Determines necessary length of new array and sets its size
353 // Lot of space in such defined array will be probably
354 // vacant after the analysis, but this will be corrected
355 // by Compress() method
360 // Input arrays indexes
362 Int_t tsStTL, tsStTR, tsOK;
363 // Time stamps ofinput arrays
364 Int_t tsNew;// New time stamp (output array)
367 // New status record :
369 // 1. bit ... _TEMP_L_STATE
370 // 2. bit ... _TEMP_R_STATE
371 Char_t lastBitStatus = 100;
373 AliDCSValue *valStTL, *valStTR, *valOK;
374 // Pointers to input arrays records (input arrays are TObjArrays
375 // containing objects of type AliDCSValue
377 tsStTR = ( (AliDCSValue *)arrStTR->At(0) )->GetTimeStamp() - fStTLDelay;
378 tsStTL = ( (AliDCSValue *)arrStTL->At(0) )->GetTimeStamp() - fStTRDelay;
379 tsOK = ( (AliDCSValue *)arrOK->At(0) )->GetTimeStamp() - fOKDelay;
380 // Time stamps of first records in input filea are readed (and delays are substracted)
382 tsNew = (tsStTR < tsStTL) ? tsStTR : tsStTL;
383 if( tsNew > tsOK ) tsNew = tsOK;
384 // Time intervals are "prolonged" to the very eaarliest of time stamps.
385 // It means that first output time stamp will be the same as the one
386 // which is first in input arrays. Values of other DCS variables are
387 // not defined in this time yet, but they will be treated as equal to
388 // values in first records of input arrays.
390 nStTLEntries--; nStTREntries--; nOKEntries--;
391 // Indexes in the input array must not exceed last records.
393 while( (idxStTL < nStTLEntries) || (idxStTR < nStTREntries) || (idxOK < nOKEntries) )
394 { // Loop goes throug all three input files
396 valStTL = (AliDCSValue *)( arrStTL->At(idxStTL) );
397 valStTR = (AliDCSValue *)( arrStTR->At(idxStTR) );
398 valOK = (AliDCSValue *)( arrOK->At(idxOK) );
399 // Values are readed from input arrays
402 if( valOK->GetBool() ) bitStatus += 1; // 0. bit - _OK
403 if( valStTL->GetInt() == 4 ) bitStatus += 2; // 1. bit - _TEMP_L_STATE
404 if( valStTR->GetInt() == 4 ) bitStatus += 4; // 2. bit - _TEMP_R_STATE
405 // Bit map is created. *TEMP_*_STATE == 4 means "Thermometer is OK"
407 if( lastBitStatus != bitStatus )
408 { // If the status bitmap is the same as last one, it would not be stored.
409 // It will save much space.
410 fDCSData[moduleLoop]->SetValueStatus( tsNew, bitStatus );
411 // Bit map is written into the output array (if different from last value )
412 lastBitStatus = bitStatus;
416 if( idxStTL == nStTLEntries )
417 tsStTL = 0x7FFFFFFF; // = 2147483647, maximal signed Int_t number
419 tsStTL = ( (AliDCSValue *)arrStTL->At(idxStTL + 1) )->GetTimeStamp() - fStTLDelay;
421 if( idxStTR == nStTREntries )
422 tsStTR = 0x7FFFFFFF; // = 2147483647, maximal signed Int_t number
424 tsStTR = ( (AliDCSValue *)arrStTR->At(idxStTR + 1) )->GetTimeStamp() - fStTRDelay;
426 if( idxOK == nOKEntries )
427 tsOK = 0x7FFFFFFF; // = 2147483647, maximal signed Int_t number
429 tsOK = ( (AliDCSValue *)arrOK->At(idxOK + 1) )->GetTimeStamp() - fOKDelay;
430 // Reads time stamps of folowing records in the input arrays (and substracts delays).
431 // Validity of the last records in the input arrays are prolonged
434 if( tsStTL == tsOK && tsStTR == tsOK ) { tsNew = tsStTL; idxStTL++; idxStTR++; idxOK++; continue; }
435 if( tsStTL == tsStTR && tsStTR < tsOK ) { tsNew = tsStTL; idxStTL++; idxStTR++; continue; }
436 if( tsStTL == tsOK && tsOK < tsStTR ) { tsNew = tsStTL; idxStTL++; idxOK++; continue; }
437 if( tsStTR == tsOK && tsOK < tsStTL ) { tsNew = tsStTR; idxStTR++; idxOK++; continue; }
438 if( tsOK < tsStTL && tsOK < tsStTR ) { tsNew = tsOK; idxOK++; continue; }
439 if( tsStTL < tsOK && tsStTL < tsStTR ) { tsNew = tsStTL; idxStTL++; continue; }
440 /*Last possibile case*/ { tsNew = tsStTR; idxStTR++; }
442 // Index of array, whose following record have time stamp closest to just written one,
443 // is increased. If there are more records with identical time stamps meeting this condition,
444 // all correspondent indexes are increased.
448 fDCSData[moduleLoop]->Compress();
449 // Size taken by data in AliITSDCSDataSDD object is minimalized
456 } /*AliITSDCSAnalyzerSDD::AnalyzeData*/
459 //---------------------------------------------------------------
462 void AliITSDCSAnalyzerSDD::Init()
464 // Initialization of DCS DP names
468 for( Int_t iLay = 3; iLay < 5; iLay++ )
470 Int_t maxLad = ( iLay == 3) ? kNladders3 : kNladders4;
471 Int_t maxMod = ( iLay == 3) ? kNmodLad3 : kNmodLad4;
473 for(Int_t iLad=0; iLad<maxLad; iLad++)
475 for(Int_t iMod=0; iMod<maxMod;iMod++)
477 sprintf(modName,"SDD_LAYER%i_LADDER%02d_MODULE%d", iLay, iLad, iMod);
478 Int_t id = AliITSgeomTGeo::GetModuleIndex( iLay, iLad + 1, iMod + 1 ) - 240;
480 sprintf(dpName,"%s_HV",modName);
481 fHVDPNames[id]=dpName;
482 sprintf(dpName,"%s_MV",modName);
483 fMVDPNames[id]=dpName;
484 sprintf(dpName,"%s_OK",modName);
485 fOKDPNames[id]=dpName;
486 sprintf(dpName,"%s_TEMP_L",modName);
487 fTLDPNames[id]=dpName;
488 sprintf(dpName,"%s_TEMP_R",modName);
489 fTRDPNames[id]=dpName;
490 sprintf(dpName,"%s_TEMP_L_STATE",modName);
491 fTLStDPNames[id]=dpName;
492 sprintf(dpName,"%s_TEMP_R_STATE",modName);
493 fTRStDPNames[id]=dpName;
501 } /*AliITSDCSAnalyzerSDD::Init*/
503 //---------------------------------------------------------------
504 void AliITSDCSAnalyzerSDD::PrintDCSDPNames( FILE *output )
506 // Prints constructed names of DCS variables into specified file (may be even stdout or stderr)
507 for( Int_t j = 0; j < kNmodules; j++ )
509 fprintf( output, "Module %d %s %s %s %s\n",j,fHVDPNames[j].Data(),
510 fMVDPNames[j].Data(),fTLDPNames[j].Data(),fTRDPNames[j].Data());
512 } /*AliITSDCSAnalyzerSDD::PrintDCSDPNames*/
514 //---------------------------------------------------------------
516 void AliITSDCSAnalyzerSDD::Export( char *outputDCSFileName )
518 // Exports all stored AliITSDCSDataSDD type object into specified root file. Objects are named as
520 // DCSDataSDD_module<number>
522 // where <number> is in range 0..256 and it is obtained by calling
524 // AliITSgeomTGeo::GetModuleIndex( layer, ladder, moduleInLadder ) - 240
526 TFile * newFile = new TFile( outputDCSFileName, "RECREATE" );
527 if( newFile == NULL )
528 { // Creates .root file with specified name. if it is not possible,
529 // warning is displayed and exporting aborted.
530 AliWarning( Form( "Cannot create %s - export aborted ", outputDCSFileName ) );
538 for( Int_t moduleLoop = 0; moduleLoop < kNmodules; moduleLoop++ )
539 { // loops through all modules and writes appropriate object into the file
540 sprintf( buffer, "DCSDataSDD_module%i", moduleLoop );
541 if( fDCSData[moduleLoop] ) fDCSData[moduleLoop]->Write( buffer, TObject::kSingleKey );
542 } /*for( moduleLoop )*/
547 } /*AliITSDCSAnalyzerSDD::Export*/