Consolidation of the classes used to get the calibration data stores from OCDB and...
[u/mrichter/AliRoot.git] / MUON / AliMUONTrackerConditionDataMaker.cxx
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 // $Id$
17
18 #include "AliMUONTrackerConditionDataMaker.h"
19
20 ///\class AliMUONTrackerConditionDataMaker
21 ///
22 /// Producer of AliMUONVTrackerData from OCDB or Ascii file condition data
23 ///
24 /// \author Laurent Aphecetche, Subatech
25
26 ///\cond CLASSIMP
27 ClassImp(AliMUONTrackerConditionDataMaker)
28 ///\endcond
29
30 #include "AliCDBManager.h"
31 #include "AliCDBStorage.h"
32 #include "AliDCSValue.h"
33 #include "AliLog.h"
34 #include "AliMpManuIterator.h"
35 #include "AliMUON2DMap.h"
36 #include "AliMUONCalibParamND.h"
37 #include "AliMUONCalibParamNF.h"
38 #include "AliMUONCalibParamNI.h"
39 #include "AliMUONCalibrationData.h"
40 #include "AliMUONDigitCalibrator.h"
41 #include "AliMUONPadStatusMaker.h"
42 #include "AliMUONPadStatusMapMaker.h"
43 #include "AliMUONTrackerData.h"
44 #include "AliMUONTrackerIO.h"
45 #include "AliMpArrayI.h"
46 #include "AliMpConstants.h"
47 #include "AliMpDCSNamer.h"
48 #include "AliMpDDLStore.h"
49 #include "AliMpDEManager.h"
50 #include "AliMpDetElement.h"
51 #include "TClass.h"
52 #include "TMap.h"
53 #include "TObjString.h"
54 #include "Riostream.h"
55 #include "TString.h"
56 #include <sstream>
57
58 //_____________________________________________________________________________
59 AliMUONTrackerConditionDataMaker::AliMUONTrackerConditionDataMaker(Int_t runNumber, const char* ocdbPath, const char* type):
60 AliMUONVTrackerDataMaker(),
61 fData(0x0),
62 fSource(Form("%s-%010d-%s",ocdbPath,runNumber,type))
63 {
64   /// ctor from OCDB
65
66   AliCDBStorage* storage = AliCDBManager::Instance()->GetDefaultStorage();
67         
68         AliCDBManager::Instance()->SetDefaultStorage(ocdbPath);
69
70   Int_t startOfValidity;
71   AliMUONVStore* store = CreateStore(runNumber,ocdbPath,type,startOfValidity);
72   AliInfo(Form("runNumber=%d ocdbPath=%s type=%s startOfValidity=%d store=%p",
73                runNumber,ocdbPath,type,startOfValidity,store));
74   if ( store )
75   {
76     fData = CreateData(type,*store,startOfValidity);
77   }  
78
79   delete store;
80   
81   AliCDBManager::Instance()->SetDefaultStorage(storage);
82 }
83
84 //_____________________________________________________________________________
85 AliMUONTrackerConditionDataMaker::AliMUONTrackerConditionDataMaker(const char* filename, const char* type):
86 AliMUONVTrackerDataMaker(),
87 fData(0x0),
88 fSource(Form("%s-%s",filename,type))
89 {
90   /// ctor from an ASCII file
91   
92   TString sFilename(gSystem->ExpandPathName(filename));
93   
94   std::ifstream in(sFilename.Data());
95   if (in.good()) 
96   {
97     std::ostringstream stream;
98     char line[1024];
99     while ( in.getline(line,1024) )
100     {
101       stream << line << "\n";    
102     }
103   
104     in.close();
105   
106     Int_t dummy;
107     
108     AliMUONVStore* store = CreateStore(-1,stream.str().c_str(),type,dummy);
109     
110     if ( store )
111     {
112       fData = CreateData(type,*store,dummy);
113     }
114     delete store;
115   }
116 }
117
118 //_____________________________________________________________________________
119 AliMUONTrackerConditionDataMaker::AliMUONTrackerConditionDataMaker(const char* data, const char* type, Bool_t) :
120 AliMUONVTrackerDataMaker(),
121 fData(0x0),
122 fSource(Form("direct-%s",type))
123 {
124   /// ctor from a string containing the ASCII data
125   /// the last parameter is there just to distinguish this ctor from the previous one
126   
127   Int_t dummy;
128   
129   AliMUONVStore* store = CreateStore(-1,data,type,dummy);
130   
131   if ( store )
132   {
133     fData = CreateData(type,*store,dummy);
134   }
135   delete store;
136   
137 }
138
139 //_____________________________________________________________________________
140 AliMUONTrackerConditionDataMaker::~AliMUONTrackerConditionDataMaker()
141 {
142   /// dtor
143   delete fData;
144 }
145
146
147 //_____________________________________________________________________________
148 AliMUONVTrackerData*
149 AliMUONTrackerConditionDataMaker::CreateData(const char* type, AliMUONVStore& store, Int_t startOfValidity)
150 {
151   /// Create the data source 
152   AliMUONVTrackerData* data(0x0);
153   
154   TString stype(type);
155   stype.ToUpper();
156   
157   if ( stype == "CAPACITANCES" )
158   {    
159     data = new AliMUONTrackerData(Form("CAPA%d",startOfValidity),"Capacitances",2,kTRUE);
160     data->SetDimensionName(0,"Capa");
161     data->SetDimensionName(1,"Injection gain");    
162   }
163   else if ( stype == "CONFIG" ) 
164   {
165     data = new AliMUONTrackerData(Form("CONFIG%d",startOfValidity),"Configuration",1);
166     data->SetDimensionName(0,"there");
167     data->DisableChannelLevel();
168   }
169   else if ( stype == "GAINS" ) 
170   {
171     data = new AliMUONTrackerData(Form("GAIN%d",startOfValidity),"Gains",7,kTRUE);
172     data->SetDimensionName(0,"gain");
173     data->SetDimensionName(1,"a1");
174     data->SetDimensionName(2,"a2");
175     data->SetDimensionName(3,"thres");
176     data->SetDimensionName(4,"qual1");
177     data->SetDimensionName(5,"qual2");
178     data->SetDimensionName(6,"sat");    
179   }
180   else if ( stype == "HV" ) 
181   {
182     data = new AliMUONTrackerData(Form("HV%d",startOfValidity),"High Voltages",1); //,!isSingleEvent);
183                 data->SetDimensionName(0,"HV");
184   }
185   else if ( stype == "OCCUPANCY" ) 
186   {
187     data = new AliMUONTrackerData(Form("OCC%d",startOfValidity),"OccupancyMap",store);
188     data->SetDimensionName(0,"One");
189     return data; // important to return now to avoid the data->Add(store) later on...
190   }
191   else if ( stype == "PEDESTALS" ) 
192   {
193     data  = new AliMUONTrackerData(Form("PED%d",startOfValidity),"Pedestals",2,kTRUE);
194     data->SetDimensionName(0,"Mean");
195     data->SetDimensionName(1,"Sigma");    
196   }
197   else if ( stype == "STATUS" ) 
198   {
199     data = new AliMUONTrackerData(Form("STATUS%d",startOfValidity),"Status",1,kTRUE);
200     data->SetDimensionName(0,"Bits");
201   }
202   else if ( stype == "STATUSMAP" ) 
203   {
204     data = new AliMUONTrackerData(Form("STATUSMAP%d",startOfValidity),"Status map",2,kTRUE);
205     data->SetDimensionName(0,"Bits");
206     data->SetDimensionName(1,"Dead");
207   }
208
209   if (!data)
210   {
211     AliErrorClass(Form("Could not create data for type=%s",type));
212     return 0x0;
213   }
214   
215   data->Add(store);
216   
217   return data;
218 }
219
220 //_____________________________________________________________________________
221 AliMUONVStore*
222 AliMUONTrackerConditionDataMaker::CreateHVStore(TMap& m)
223 {
224   /// Create a store from hv values
225   
226   AliMUONVStore* store = new AliMUON2DMap(kTRUE);
227   
228   TIter next(&m);
229   TObjString* s;
230   AliMpDCSNamer hvNamer("TRACKER");
231   
232   while ( ( s = static_cast<TObjString*>(next()) ) )
233   {
234     TString name(s->String());
235     
236     Int_t hvIndex = hvNamer.DCSIndexFromDCSAlias(name.Data());
237
238     if ( hvIndex >= 0 )
239     {
240       // skip switches
241       continue;      
242     }
243
244     Int_t detElemId = hvNamer.DetElemIdFromDCSAlias(name.Data());
245     
246     if ( !AliMpDEManager::IsValidDetElemId(detElemId) )
247     {
248       AliErrorClass(Form("Got an invalid DE = %d from alias = %s",
249                          detElemId,name.Data()));
250       continue;
251     }
252     
253     Int_t nPCBs = hvNamer.NumberOfPCBs(detElemId);
254     Int_t nindex = nPCBs ? nPCBs : 1;
255     
256     AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
257     
258     for ( int i = 0 ; i < nindex; ++i )
259     {
260       Float_t switchValue(1.0);
261       
262       if ( nPCBs ) 
263       {
264         TString switchName(hvNamer.DCSSwitchName(detElemId,i));
265
266         TPair* p = static_cast<TPair*>(m.FindObject(switchName.Data()));
267         TObjArray* a = static_cast<TObjArray*>(p->Value());
268         
269         switchValue = AliMUONPadStatusMaker::SwitchValue(*a);                                           
270       }
271       
272       const AliMpArrayI* manus = de->ManusForHV(i);
273       
274       if (!manus) continue;
275       
276       TPair* p = static_cast<TPair*>(m.FindObject(name.Data()));
277       TObjArray* a = static_cast<TObjArray*>(p->Value());
278       TIter n2(a);
279       AliDCSValue* v;
280       Float_t hvValue(0);
281       Int_t n(0);
282       while ( ( v = static_cast<AliDCSValue*>(n2()) ) )
283       {
284         hvValue += v->GetFloat();
285         ++n;
286       }
287       hvValue *= switchValue;  
288       
289       if ( n ) hvValue /= n;
290       
291       Int_t nofChannels(AliMpConstants::ManuNofChannels());
292       
293       for ( Int_t k = 0 ; k < manus->GetSize(); ++k )
294       {
295         Int_t manuId = manus->GetValue(k);
296         AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>(store->FindObject(detElemId,manuId));
297         if ( ! param ) 
298         {
299           param = new AliMUONCalibParamND(1,nofChannels,detElemId,manuId,0);
300           store->Add(param);
301         }
302         for ( Int_t j = 0 ; j < nofChannels; ++j )
303         {
304           param->SetValueAsDouble(j,0,hvValue);
305         }
306       }
307     }
308   }
309   
310   return store;
311   
312 }
313
314 //_____________________________________________________________________________
315 AliMUONVStore*
316 AliMUONTrackerConditionDataMaker::CreateStatusStore(Int_t runNumber)
317 {
318   /// Get the status store
319   
320   AliMUONDigitCalibrator calibrator(runNumber);
321   
322   AliMUONVStore* sm = new AliMUON2DMap(kTRUE);
323   
324   AliMpManuIterator it;
325   Int_t detElemId, manuId;
326   
327   while (it.Next(detElemId,manuId))
328   {
329     AliMUONVCalibParam* np = new AliMUONCalibParamNI(1,AliMpConstants::ManuNofChannels(),detElemId,manuId);
330     for ( Int_t i = 0; i < np->Size(); ++i ) 
331     {
332       Int_t value = calibrator.PadStatus(detElemId,manuId,i);
333       np->SetValueAsInt(i,0,value); // "raw" value of the status
334     }
335     sm->Add(np);
336   }
337   
338   return sm;
339 }
340
341 //_____________________________________________________________________________
342 AliMUONVStore*
343 AliMUONTrackerConditionDataMaker::CreateStatusMapStore(Int_t runNumber)
344 {
345   /// Get the status map, and polish it a bit for representation purposes
346   
347   AliMUONDigitCalibrator calibrator(runNumber);
348   
349   AliMUONVStore* sm = new AliMUON2DMap(kTRUE);
350   
351   AliMpManuIterator it;
352   Int_t detElemId, manuId;
353   
354   while (it.Next(detElemId,manuId))
355   {
356     AliMUONVCalibParam* np = new AliMUONCalibParamNI(2,AliMpConstants::ManuNofChannels(),detElemId,manuId);
357     for ( Int_t i = 0; i < np->Size(); ++i ) 
358     {
359       Int_t value = calibrator.StatusMap(detElemId,manuId,i);
360       Int_t channelIsDead = ( value & AliMUONPadStatusMapMaker::SelfDeadMask() );
361       np->SetValueAsInt(i,0,value); // "raw" value of the status map
362       np->SetValueAsInt(i,1,channelIsDead); // simple 0 or 1 for this channel
363     }
364     sm->Add(np);
365   }
366   
367   return sm;
368 }
369
370 //_____________________________________________________________________________
371 AliMUONVStore*
372 AliMUONTrackerConditionDataMaker::CreateStore(Int_t runNumber, 
373                                               const char* source, 
374                                               const char* type, 
375                                               Int_t& startOfValidity)
376 {
377   /// Create the store by reading it from OCDB or from an ASCII file
378   
379   TString stype(type);
380   stype.ToUpper();
381   
382   AliMUONVStore* store(0x0);
383   
384   startOfValidity = 0;
385   
386   Bool_t ocdb = (runNumber>=0);
387   
388   if ( stype == "CAPACITANCES" )
389   {    
390     if ( ocdb ) 
391     {
392       store = AliMUONCalibrationData::CreateCapacitances(runNumber,&startOfValidity);    
393     }
394     else
395     {
396       store = new AliMUON2DMap(20000);
397       AliMUONTrackerIO::DecodeCapacitances(source,*store);
398     }
399   }
400   else if ( stype == "CONFIG" ) 
401   {
402     AliMUONVStore* tmp(0x0);
403     if ( ocdb ) 
404     {
405       tmp = AliMUONCalibrationData::CreateConfig(runNumber,&startOfValidity);
406     }
407     else
408     {
409       tmp = new AliMUON2DMap(kTRUE);
410       Bool_t changed(kFALSE);
411       AliMUONTrackerIO::DecodeConfig(source,*tmp,changed);
412     }
413     if ( tmp ) 
414     {
415       store = ExpandConfig(*tmp);      
416     }
417     delete tmp;
418   }
419   else if ( stype == "GAINS" ) 
420   {
421     AliMUONVStore* gains(0x0);
422     if ( ocdb ) 
423     {
424       gains = AliMUONCalibrationData::CreateGains(runNumber,&startOfValidity);
425     }
426     else
427     {
428       gains = new AliMUON2DMap(kTRUE);
429       TString comment;
430       AliMUONTrackerIO::DecodeGains(source,*gains,comment);
431     }
432     store = PatchGainStore(*gains);
433     delete gains;
434   }
435   else if ( stype == "OCCUPANCY" ) 
436   {
437     if ( ocdb ) 
438     {
439       store = AliMUONCalibrationData::CreateOccupancyMap(runNumber,&startOfValidity);
440     }
441     else
442     {
443       store = new AliMUON2DMap(kTRUE);
444       AliMUONTrackerIO::DecodeOccupancy(source,*store);
445     }
446   }
447   else if ( stype == "PEDESTALS" ) 
448   {
449     if ( ocdb ) 
450     {
451       store = AliMUONCalibrationData::CreatePedestals(runNumber,&startOfValidity);
452     }
453     else
454     {
455       store = new AliMUON2DMap(kTRUE);
456       AliMUONTrackerIO::DecodePedestals(source,*store);
457     }
458   }
459   
460   /// Below are source that can only be accessed from OCDB
461   if (!store && !ocdb) 
462   {
463     return 0x0;
464   }
465   
466   if ( stype == "HV" ) 
467   {
468     TMap* m = AliMUONCalibrationData::CreateHV(runNumber,&startOfValidity);
469                 store = CreateHVStore(*m);
470     delete m;
471   }
472   else if ( stype == "STATUS" ) 
473   {
474     store = CreateStatusStore(runNumber);
475   }
476   else if ( stype == "STATUSMAP" ) 
477   {
478     store = CreateStatusMapStore(runNumber);
479   }
480   
481   return store;
482 }
483
484 //_____________________________________________________________________________
485 AliMUONVStore*
486 AliMUONTrackerConditionDataMaker::ExpandConfig(const AliMUONVStore& manuConfig)
487 {
488   /// Convert the config from manu level to channel level (just to
489   /// be able to add it correctly to the trackerdata...)
490   
491   AliMUONVStore* store = manuConfig.Create();
492   
493   TIter next(manuConfig.CreateIterator());
494   AliMUONVCalibParam* p;
495   
496   while ( ( p = static_cast<AliMUONVCalibParam*>(next()) ) )
497   {
498     AliMUONVCalibParam* c = new AliMUONCalibParamNF(1,AliMpConstants::ManuNofChannels(),p->ID0(),p->ID1(),0.0);
499     
500     AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(p->ID0());
501     
502     for ( Int_t i = 0; i < c->Size(); ++i ) 
503     {
504       if ( de->IsExistingChannel(p->ID1(),i) )
505       {
506         c->SetValueAsFloat(i,0,1.0);        
507       }
508     }
509     
510     store->Add(c);
511   }
512   return store;
513 }
514
515 //_____________________________________________________________________________
516 Long64_t 
517 AliMUONTrackerConditionDataMaker::Merge(TCollection*)
518 {
519   /// Merge
520   AliError("Not implemented. Does it have sense ?");
521   return 0;
522 }
523
524 //_____________________________________________________________________________
525 AliMUONVStore*
526 AliMUONTrackerConditionDataMaker::PatchGainStore(const AliMUONVStore& gains)
527 {
528   /// Polish the gain store : 
529   /// a) adding a dimension, computed from a1, and called gain = 1/a1/0.2 
530   ///     where 0.2 is internal capa in pF, and gain is then in mV/fC
531   /// b) splitting the quality in two
532   
533   AliMUONVStore* store = gains.Create();
534   
535   TIter next(gains.CreateIterator());
536   AliMUONVCalibParam* param;
537   
538   while ( ( param = static_cast<AliMUONVCalibParam*>(next()) ) ) 
539   {
540     AliMUONVCalibParam* nd = new AliMUONCalibParamND(param->Dimension()+2,
541                                                      param->Size(),
542                                                      param->ID0(),
543                                                      param->ID1());
544     for ( Int_t i = 0; i < param->Size(); ++i ) 
545     {
546       
547       Int_t qual = param->ValueAsInt(i,3);
548                         Int_t q1 = (qual & 0xF0) >> 4;  // linear fit quality
549                         Int_t q2 = qual & 0xF;          // parabolic fit quality
550                         Double_t gain = 0.0;
551       
552       if ( param->ValueAsFloat(i,0) > 1E-9 ) gain = 1.0/param->ValueAsFloat(i,0)/0.2;
553                         
554       nd->SetValueAsDouble(i,0,gain); // gain
555       nd->SetValueAsDouble(i,1,param->ValueAsFloat(i,0)); // a1
556       nd->SetValueAsDouble(i,2,param->ValueAsFloat(i,1)); // a2
557       nd->SetValueAsInt(i,3,param->ValueAsInt(i,2)); // thres
558       nd->SetValueAsInt(i,4,q1); // qual1
559       nd->SetValueAsInt(i,5,q2); // qual2
560       nd->SetValueAsInt(i,6,param->ValueAsInt(i,4)); // sat
561     }
562     store->Add(nd);
563   }
564   
565   return store;
566 }
567