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=0; // 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) AliWarning( Form("DCS HV alias %s not found!\n", fHVDPNames[moduleLoop].Data()) );
124 TObjArray* arrMV = (TObjArray*) dcsMap->GetValue( fMVDPNames[moduleLoop].Data() );
125 if(!arrMV) AliWarning( Form("DCS MV alias %s not found!\n", fMVDPNames[moduleLoop].Data()));
127 TObjArray* arrOK = (TObjArray*) dcsMap->GetValue( fOKDPNames[moduleLoop].Data() );
128 if(!arrOK) AliWarning( Form("DCS MOD_OK alias %s not found!\n", fOKDPNames[moduleLoop].Data()));
130 TObjArray* arrTL = (TObjArray*) dcsMap->GetValue( fTLDPNames[moduleLoop].Data() );
131 if(!arrTL) AliWarning( Form("DCS TEMP_L alias %s not found!\n", fTLDPNames[moduleLoop].Data()));
133 TObjArray* arrTR = (TObjArray*) dcsMap->GetValue( fTRDPNames[moduleLoop].Data() );
134 if(!arrTR) AliWarning( Form("DCS TEMP_R alias %s not found!\n", fTRDPNames[moduleLoop].Data()));
136 TObjArray* arrStTL = (TObjArray*) dcsMap->GetValue( fTLStDPNames[moduleLoop].Data() );
137 if(!arrStTL) AliWarning( Form("DCS TEMP_L_STATE alias %s not found!\n", fTLStDPNames[moduleLoop].Data()));
139 TObjArray* arrStTR = (TObjArray*) dcsMap->GetValue( fTRStDPNames[moduleLoop].Data() );
140 if(!arrStTR) AliWarning( Form("DCS TEMP_R_STATE alias %s not found!\n", fTRStDPNames[moduleLoop].Data()));
142 lastTLValUpper = -1e-10;
143 lastTLValLower = +1e+10;
144 lastTRValUpper = -1e-10;
145 lastTRValLower = +1e+10;
146 lastHVValUpper = -1e-10;
147 lastHVValLower = +1e+10;
148 lastMVValUpper = -1e-10;
149 lastMVValLower = +1e+10;
150 // First value of any DCS variable must be written
155 nEntries = arrTL->GetEntries();
156 fDCSData[moduleLoop]->SetNPointsTempLeft( nEntries );
157 // Left temperature array size is set
159 for( Int_t tlLoop = 0; tlLoop < nEntries; tlLoop++ )
160 { // Left temerature values are copied into the AliITSDCSDataSDD TempLeft array
161 valToProcess = (AliDCSValue *)(arrTL->At(tlLoop));
162 valToProcessFloat = valToProcess->GetFloat();
163 // Value is readed from the input array
165 if( lastTLValLower <= valToProcessFloat && valToProcessFloat <= lastTLValUpper ) continue;
166 // Value did not cross the treshold (upper neither lower),
167 // it is not necessary to store it.
168 fDCSData[moduleLoop]->SetValueTempLeft( valToProcess->GetTimeStamp() - fTLDelay, valToProcessFloat );
170 lastTLValLower = valToProcessFloat * ( 1.0 - fTLThresholdFrac );
171 lastTLValUpper = valToProcessFloat * ( 1.0 + fTLThresholdFrac );
172 // New tresholds are set
180 nEntries = arrTR->GetEntries();
181 fDCSData[moduleLoop]->SetNPointsTempRight( nEntries );
182 // Right temperature array size is set
184 for( Int_t trLoop = 0; trLoop < nEntries; trLoop++ )
185 { // Right temerature values are copied into the AliITSDCSDataSDD TempRight array
186 valToProcess = (AliDCSValue *)(arrTR->At(trLoop));
187 valToProcessFloat = valToProcess->GetFloat();
188 // Value is readed from the input array
190 if( lastTRValLower <= valToProcessFloat && valToProcessFloat <= lastTRValUpper ) continue;
191 // Value did not cross the treshold (upper neither lower),
192 // it is not necessary to store it.
193 fDCSData[moduleLoop]->SetValueTempRight( valToProcess->GetTimeStamp() - fTRDelay, valToProcessFloat );
195 lastTRValLower = valToProcessFloat * ( 1.0 - fTRThresholdFrac );
196 lastTRValUpper = valToProcessFloat * ( 1.0 + fTRThresholdFrac );
197 // New tresholds are set
205 nEntries = arrHV->GetEntries();
206 fDCSData[moduleLoop]->SetNPointsHV( nEntries );
207 // HV array size is set
209 for( Int_t hvLoop = 0; hvLoop < nEntries; hvLoop++ )
210 { // HV values are copied into the AliITSDCSDataSDD HV array
211 valToProcess = (AliDCSValue *)(arrHV->At(hvLoop));
212 valToProcessFloat = valToProcess->GetFloat();
213 // Value is readed from the input array
214 if( lastHVValLower <= valToProcessFloat && valToProcessFloat <= lastHVValUpper ) continue;
215 // Value did not cross the treshold (upper neither lower),
216 // it is not necessary to store it.
217 fDCSData[moduleLoop]->SetValueHV( valToProcess->GetTimeStamp() - fHVDelay, valToProcessFloat );
219 lastHVValLower = valToProcessFloat * ( 1.0 - fHVThresholdFrac );
220 lastHVValUpper = valToProcessFloat * ( 1.0 + fHVThresholdFrac );
221 // New tresholds are set
231 nEntries = arrMV->GetEntries();
232 fDCSData[moduleLoop]->SetNPointsMV( nEntries );
233 // MV array size is set
235 for( Int_t mvLoop = 0; mvLoop < nEntries; mvLoop++ )
236 { // MV values are copied into the AliITSDCSDataSDD MV array
237 valToProcess = (AliDCSValue *)(arrMV->At(mvLoop));
238 valToProcessFloat = valToProcess->GetFloat();
239 // Value is readed from the input array
240 if( lastMVValLower <= valToProcessFloat && valToProcessFloat <= lastMVValUpper ) continue;
241 // Value did not cross the treshold (upper neither lower),
242 // it is not necessary to store it.
243 fDCSData[moduleLoop]->SetValueMV( valToProcess->GetTimeStamp() - fMVDelay, valToProcessFloat );
245 lastMVValLower = valToProcessFloat * ( 1.0 - fMVThresholdFrac );
246 lastMVValUpper = valToProcessFloat * ( 1.0 + fMVThresholdFrac );
247 // New treshold is ser
254 /* Following part of the code is responsibile for the condensing of all status information given by DCS
255 into one array of Char_t. Each record of this array is in principle a bit map :
258 1. bit ... _TEMP_L_STATE
259 2. bit ... _TEMP_R_STATE
261 Each record have its own time stamp. Because there are three inputs with independent time stamp,
262 some algorithm which assigns new time stamp to bitmap according to three input time stamps is
265 Let's vizualize time stamps of the three input arrays. There is time on x-axis :
267 +------------+---------------------+------
269 +-----++------+----+--------+------------+------
270 | | | | | _TEMP_L_STATE
271 +--+------+---+--+-------+-----+--------+---+------
272 | | | | | | _TEMP_R_STATE
273 +-------------+----------+-----+--------+---+------
275 | | | | | | | | | | |
276 V V V V V V V V V V V
278 +---+----+-+--+---+---+--+-----+--------+---+------
279 | | | | | | | | | | | Status bitmap
280 +---+----+-+--+---+---+--+-----+--------+---+------
283 Principle of combining three status records into one is visible from the picture.
284 If there are two sequent records with the same status bitmap, they are joined into
285 one (with the time stamp of the earliest one).
288 Int_t nStTLEntries = 0;
289 Int_t nStTREntries = 0;
290 Int_t nOKEntries = 0;
292 bool arrStTLcreated = false;
293 bool arrStTRcreated = false;
294 bool arrOKcreated = false;
297 nStTLEntries = arrStTL->GetEntries();
299 { arrStTL = new TObjArray; arrStTLcreated = true; }
302 nStTREntries = arrStTR->GetEntries();
304 { arrStTR = new TObjArray; arrStTRcreated = true; }
307 nOKEntries = arrOK->GetEntries();
309 { arrOK = new TObjArray; arrOKcreated = true; }
310 // Gets number of _STAT_L, _STAT_R and _OK values stored in dcsMap. If any array does
311 // not exist, it must be created (and it will be filled by 0 status later)
313 if( nStTLEntries < 1 )
314 { // TObjArray arrStTL is empty. This would cause segmentation violation during
315 // the condensing, so this case must be handled before algorithm starts
316 AliWarning( Form( "%s contains no data!\n", fTLStDPNames[moduleLoop].Data() ) );
318 arrStTL->Add( new AliDCSValue( (Int_t)0, 0x7FFFFFFF ) );
319 // 0x7FFFFFFF = 2147483647, maximal signed Int_t number. Left temperature
320 // sensor will be regarded as switched-off during whole run.
323 if( nStTREntries < 1 )
324 { // TObjArray arrStTR is empty. This would cause segmentation violation during
325 // the condensing, so this case must be handled before algorithm starts
326 AliWarning( Form( "%s contains no data!\n", fTRStDPNames[moduleLoop].Data() ) );
328 arrStTR->Add( new AliDCSValue( (Int_t)0, 0x7FFFFFFF ) );
329 // 0x7FFFFFFF = 2147483647, maximal signed Int_t number. Right temperature
330 // sensor will be regarded as switched-off during whole run.
334 { // TObjArray arrOK is empty. This would cause segmentation violation during
335 // the condensing, so this case must be handled before algorithm starts
336 AliWarning( Form( "%s contains no data!\n", fOKDPNames[moduleLoop].Data() ) );
338 arrOK->Add( new AliDCSValue( (Bool_t)0, 0x7FFFFFFF ) );
339 // 0x7FFFFFFF = 2147483647, maximal signed Int_t number.
340 // Module will be regarded as switched-off during whole run.
346 // Condensing would work properly only in the case that
347 // the input arrays are sorted by time
349 Int_t nEntriesMax = nStTLEntries + nStTREntries + nOKEntries;
350 fDCSData[moduleLoop]->SetNPointsStatus( nEntriesMax );
351 // Determines necessary length of new array and sets its size
352 // Lot of space in such defined array will be probably
353 // vacant after the analysis, but this will be corrected
354 // by Compress() method
359 // Input arrays indexes
361 Int_t tsStTL, tsStTR, tsOK;
362 // Time stamps ofinput arrays
363 Int_t tsNew;// New time stamp (output array)
366 // New status record :
368 // 1. bit ... _TEMP_L_STATE
369 // 2. bit ... _TEMP_R_STATE
370 Char_t lastBitStatus = 100;
372 AliDCSValue *valStTL, *valStTR, *valOK;
373 // Pointers to input arrays records (input arrays are TObjArrays
374 // containing objects of type AliDCSValue
376 tsStTR = ( (AliDCSValue *)arrStTR->At(0) )->GetTimeStamp() - fStTLDelay;
377 tsStTL = ( (AliDCSValue *)arrStTL->At(0) )->GetTimeStamp() - fStTRDelay;
378 tsOK = ( (AliDCSValue *)arrOK->At(0) )->GetTimeStamp() - fOKDelay;
379 // Time stamps of first records in input filea are readed (and delays are substracted)
381 tsNew = (tsStTR < tsStTL) ? tsStTR : tsStTL;
382 if( tsNew > tsOK ) tsNew = tsOK;
383 // Time intervals are "prolonged" to the very eaarliest of time stamps.
384 // It means that first output time stamp will be the same as the one
385 // which is first in input arrays. Values of other DCS variables are
386 // not defined in this time yet, but they will be treated as equal to
387 // values in first records of input arrays.
389 nStTLEntries--; nStTREntries--; nOKEntries--;
390 // Indexes in the input array must not exceed last records.
392 while( (idxStTL < nStTLEntries) || (idxStTR < nStTREntries) || (idxOK < nOKEntries) )
393 { // Loop goes throug all three input files
395 valStTL = (AliDCSValue *)( arrStTL->At(idxStTL) );
396 valStTR = (AliDCSValue *)( arrStTR->At(idxStTR) );
397 valOK = (AliDCSValue *)( arrOK->At(idxOK) );
398 // Values are readed from input arrays
401 if( valOK->GetBool() ) bitStatus += 1; // 0. bit - _OK
402 if( valStTL->GetInt() == 4 ) bitStatus += 2; // 1. bit - _TEMP_L_STATE
403 if( valStTR->GetInt() == 4 ) bitStatus += 4; // 2. bit - _TEMP_R_STATE
404 // Bit map is created. *TEMP_*_STATE == 4 means "Thermometer is OK"
406 if( lastBitStatus != bitStatus )
407 { // If the status bitmap is the same as last one, it would not be stored.
408 // It will save much space.
409 fDCSData[moduleLoop]->SetValueStatus( tsNew, bitStatus );
410 // Bit map is written into the output array (if different from last value )
411 lastBitStatus = bitStatus;
415 if( idxStTL == nStTLEntries )
416 tsStTL = 0x7FFFFFFF; // = 2147483647, maximal signed Int_t number
418 tsStTL = ( (AliDCSValue *)arrStTL->At(idxStTL + 1) )->GetTimeStamp() - fStTLDelay;
420 if( idxStTR == nStTREntries )
421 tsStTR = 0x7FFFFFFF; // = 2147483647, maximal signed Int_t number
423 tsStTR = ( (AliDCSValue *)arrStTR->At(idxStTR + 1) )->GetTimeStamp() - fStTRDelay;
425 if( idxOK == nOKEntries )
426 tsOK = 0x7FFFFFFF; // = 2147483647, maximal signed Int_t number
428 tsOK = ( (AliDCSValue *)arrOK->At(idxOK + 1) )->GetTimeStamp() - fOKDelay;
429 // Reads time stamps of folowing records in the input arrays (and substracts delays).
430 // Validity of the last records in the input arrays are prolonged
433 if( tsStTL == tsOK && tsStTR == tsOK ) { tsNew = tsStTL; idxStTL++; idxStTR++; idxOK++; continue; }
434 if( tsStTL == tsStTR && tsStTR < tsOK ) { tsNew = tsStTL; idxStTL++; idxStTR++; continue; }
435 if( tsStTL == tsOK && tsOK < tsStTR ) { tsNew = tsStTL; idxStTL++; idxOK++; continue; }
436 if( tsStTR == tsOK && tsOK < tsStTL ) { tsNew = tsStTR; idxStTR++; idxOK++; continue; }
437 if( tsOK < tsStTL && tsOK < tsStTR ) { tsNew = tsOK; idxOK++; continue; }
438 if( tsStTL < tsOK && tsStTL < tsStTR ) { tsNew = tsStTL; idxStTL++; continue; }
439 /*Last possibile case*/ { tsNew = tsStTR; idxStTR++; }
441 // Index of array, whose following record have time stamp closest to just written one,
442 // is increased. If there are more records with identical time stamps meeting this condition,
443 // all correspondent indexes are increased.
447 fDCSData[moduleLoop]->Compress();
448 // Size taken by data in AliITSDCSDataSDD object is minimalized
450 if( arrStTRcreated ) delete arrStTR;
451 if( arrStTLcreated ) delete arrStTL;
452 if( arrOKcreated ) delete arrOK;
459 } /*AliITSDCSAnalyzerSDD::AnalyzeData*/
462 //---------------------------------------------------------------
465 void AliITSDCSAnalyzerSDD::Init()
467 // Initialization of DCS DP names
470 for( Int_t iLay = 3; iLay < 5; iLay++ ){
471 Int_t maxLad = ( iLay == 3) ? kNladders3 : kNladders4;
472 Int_t maxMod = ( iLay == 3) ? kNmodLad3 : kNmodLad4;
474 for(Int_t iLad=0; iLad<maxLad; iLad++){
475 for(Int_t iMod=0; iMod<maxMod;iMod++){
476 modName.Form("SDD_LAYER%i_LADDER%02d_MODULE%d", iLay, iLad, iMod);
477 Int_t id = AliITSgeomTGeo::GetModuleIndex( iLay, iLad + 1, iMod + 1 ) - 240;
479 fHVDPNames[id].Form("%s_HV",modName.Data());
480 fMVDPNames[id].Form("%s_MV",modName.Data());
481 fOKDPNames[id].Form("%s_OK",modName.Data());
482 fTLDPNames[id].Form("%s_TEMP_L",modName.Data());
483 fTRDPNames[id].Form("%s_TEMP_R",modName.Data());
484 fTLStDPNames[id].Form("%s_TEMP_L_STATE",modName.Data());
485 fTRStDPNames[id].Form("%s_TEMP_R_STATE",modName.Data());
493 } /*AliITSDCSAnalyzerSDD::Init*/
495 //---------------------------------------------------------------
496 void AliITSDCSAnalyzerSDD::PrintDCSDPNames( FILE *output )
498 // Prints constructed names of DCS variables into specified file (may be even stdout or stderr)
499 for( Int_t j = 0; j < kNmodules; j++ )
501 fprintf( output, "Module %d %s %s %s %s\n",j,fHVDPNames[j].Data(),
502 fMVDPNames[j].Data(),fTLDPNames[j].Data(),fTRDPNames[j].Data());
504 } /*AliITSDCSAnalyzerSDD::PrintDCSDPNames*/
506 //---------------------------------------------------------------
508 void AliITSDCSAnalyzerSDD::Export( char *outputDCSFileName )
510 // Exports all stored AliITSDCSDataSDD type object into specified root file. Objects are named as
512 // DCSDataSDD_module<number>
514 // where <number> is in range 0..256 and it is obtained by calling
516 // AliITSgeomTGeo::GetModuleIndex( layer, ladder, moduleInLadder ) - 240
518 TFile * newFile = new TFile( outputDCSFileName, "RECREATE" );
519 if( newFile == NULL )
520 { // Creates .root file with specified name. if it is not possible,
521 // warning is displayed and exporting aborted.
522 AliWarning( Form( "Cannot create %s - export aborted ", outputDCSFileName ) );
530 for( Int_t moduleLoop = 0; moduleLoop < kNmodules; moduleLoop++ )
531 { // loops through all modules and writes appropriate object into the file
532 snprintf( buffer, 99 , "DCSDataSDD_module%i", moduleLoop );
533 if( fDCSData[moduleLoop] ) fDCSData[moduleLoop]->Write( buffer, TObject::kSingleKey );
534 } /*for( moduleLoop )*/
539 } /*AliITSDCSAnalyzerSDD::Export*/