Correct use of ROOT_INCLUDE_DIR
[u/mrichter/AliRoot.git] / MUON / MUONmapping / AliMpDCSNamer.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 "AliMpDCSNamer.h"
19
20 #include "AliCodeTimer.h"
21 #include "AliLog.h"
22 #include "AliMpArea.h"
23 #include "AliMpDEIterator.h"
24 #include "AliMpDEManager.h"
25 #include "AliMpHelper.h"
26 #include "AliMpMotifMap.h"
27 #include "AliMpMotifPosition.h"
28 #include "AliMpSector.h"
29 #include "AliMpSegmentation.h"
30 #include "AliMpSlat.h"
31 #include "AliMpConstants.h"
32 #include <Riostream.h>
33 #include <TMap.h>
34 #include <TObjArray.h>
35 #include <TObjString.h>
36 #include <TString.h>
37 #include <TSystem.h>
38
39 //-----------------------------------------------------------------------------
40 /// \class AliMpDCSNamer
41 /// 
42 /// A utility class to manage DCS aliases names, in particular the
43 /// two conventions used to number the detection elements within a detector.
44 ///
45 /// \author: Laurent Aphecetche and Diego Stocco, Subatech
46 //-----------------------------------------------------------------------------
47
48 using std::cout;
49 using std::endl;
50 /// \cond CLASSIMP
51 ClassImp(AliMpDCSNamer)
52 /// \endcond
53
54 const char* AliMpDCSNamer::fgkDCSChannelSt345Pattern[] = 
55 { "MchHvLvLeft/Chamber%02dLeft/Slat%02d.actual.vMon",
56   "MchHvLvRight/Chamber%02dRight/Slat%02d.actual.vMon" 
57 };
58
59 const char* AliMpDCSNamer::fgkDCSChannelSt12Pattern[] = 
60 {
61   "MchHvLvLeft/Chamber%02dLeft/Quad%dSect%d.actual.vMon",
62   "MchHvLvRight/Chamber%02dRight/Quad%dSect%d.actual.vMon"
63 };
64
65 const char* AliMpDCSNamer::fgkDCSQuadrantPattern[] =
66 {
67   "MchHvLvLeft/Chamber%02dLeft/Quad%d",
68   "MchHvLvRight/Chamber%02dRight/Quad%d"  
69 };
70
71 const char* AliMpDCSNamer::fgkDCSChamberPattern[] =
72 {
73   "MchHvLvLeft/Chamber%02dLeft",
74   "MchHvLvRight/Chamber%02dRight"
75 };
76
77 const char* AliMpDCSNamer::fgkDCSSideTrackerName[] = { "Left", "Right" };
78
79
80 const char* AliMpDCSNamer::fgkDCSSwitchSt345Pattern = "MchDE%04dsw%d.inValue";
81
82 const char* AliMpDCSNamer::fgkDCSChannelTriggerPatternRead[] = {"MTR_%3sSIDE_MT%2i_RPC%i_HV.%14s", "MTR_%2sSIDE_MT%2i_RPC%i_HV.%14s"};
83 const char* AliMpDCSNamer::fgkDCSChannelTriggerPattern[] = {"MTR_%3sSIDE_MT%2i_RPC%i_HV.%s", "MTR_%2sSIDE_MT%2i_RPC%i_HV.%s"};
84 const char* AliMpDCSNamer::fgkDCSSideTriggerName[] = { "OUT", "IN" };
85 const char* AliMpDCSNamer::fgkDCSMeasureName[] = { "vEff", "actual.iMon" };
86
87 const char* AliMpDCSNamer::fgkDetectorName[] = { "TRACKER", "TRIGGER" };
88
89 //_____________________________________________________________________________
90 AliMpDCSNamer::AliMpDCSNamer():
91 fDetector(-1)
92 {
93   SetDetector("TRACKER");
94   /// default ctor 
95 }
96
97 //_____________________________________________________________________________
98 AliMpDCSNamer::AliMpDCSNamer(const char* detName):
99 fDetector(-1)
100 {
101   /// ctor taking the detector name as argument (either trigger or tracker)
102   SetDetector(detName);
103 }
104
105 //_____________________________________________________________________________
106 AliMpDCSNamer::~AliMpDCSNamer()
107 {
108   /// dtor
109 }
110
111 //_____________________________________________________________________________
112 Bool_t AliMpDCSNamer::SetDetector(const char* detName)
113 {
114   /// Set the detector type
115   /// \param detName = tracker, trigger
116
117   TString sDetName(detName);
118   Bool_t isOk(kTRUE);
119   sDetName.ToUpper();
120   if(sDetName.Contains(fgkDetectorName[kTrackerDet]))
121     fDetector = kTrackerDet;
122   else if(sDetName.Contains(fgkDetectorName[kTriggerDet]))
123     fDetector = kTriggerDet;
124   else {
125     AliWarning("Detector name must be either tracker or trigger. Default tracker selected");
126     isOk = kFALSE;
127   }
128   return isOk;
129 }
130
131
132 //_____________________________________________________________________________
133 void 
134 AliMpDCSNamer::AliasesAsLdif(const char* ldiffile) const
135 {
136 /// Export the aliases in LDIF format
137
138   ofstream out(ldiffile);
139   
140   TObjArray* a = CompactAliases();
141   
142   TIter next(a);
143   TObjString* s;
144
145   // Some header. host name and port probably not up to date.
146   TString detName = (fDetector == kTriggerDet) ? "MTR" : "MCH";
147
148   out << "#" << detName.Data() << " config" << endl
149       << "dn: det=" << detName.Data() <<",o=alice,dc=cern,dc=ch" << endl
150       << "objectClass: AliShuttleDetector" << endl
151       << "det: " << detName.Data() << endl
152       << "StrictRunOrder: 1" << endl
153       << "responsible: aphecetc@in2p3.fr" << endl
154       << "DCSHost: aldcs053.cern.ch" << endl
155       << "DCSPort: 4242" <<endl;
156   
157   while ( ( s = (TObjString*)(next()) ) )
158   {
159     out << "DCSalias: " << s->String().Data() << endl;
160   }
161   
162   out.close();
163   
164   delete a;
165 }
166
167 //_____________________________________________________________________________
168 TObjArray*
169 AliMpDCSNamer::CompactAliases() const
170 {
171   /// Generate a compact list of aliases, for Shuttle test
172   /// This one is completely hand-made, in contrast with GenerateAliases()
173   /// method
174
175   TObjArray* a = new TObjArray;
176   a->SetOwner(kTRUE);
177
178   switch(fDetector){
179   case kTrackerDet:
180     // St 12 (DCS Channels)
181     a->Add(new TObjString("MchHvLvRight/Chamber[00..03]Right/Quad0Sect[0..2].actual.vMon"));
182     a->Add(new TObjString("MchHvLvLeft/Chamber[00..03]Left/Quad1Sect[0..2].actual.vMon"));
183     a->Add(new TObjString("MchHvLvLeft/Chamber[00..03]Left/Quad2Sect[0..2].actual.vMon"));
184     a->Add(new TObjString("MchHvLvRight/Chamber[00..03]Right/Quad3Sect[0..2].actual.vMon"));
185   
186     // St345 (DCS Channels)
187   
188     a->Add(new TObjString("MchHvLvRight/Chamber[04..09]Right/Slat[00..08].actual.vMon"));
189     a->Add(new TObjString("MchHvLvLeft/Chamber[04..09]Left/Slat[00..08].actual.vMon"));
190
191     a->Add(new TObjString("MchHvLvRight/Chamber[06..09]Right/Slat[09..12].actual.vMon"));
192     a->Add(new TObjString("MchHvLvLeft/Chamber[06..09]Left/Slat[09..12].actual.vMon"));
193     break;
194     
195   case kTriggerDet:
196     a->Add(new TObjString("MTR_OUTSIDE_MT[11..12]Right/RPC[1..9]_HV.imon"));
197     a->Add(new TObjString("MTR_OUTSIDE_MT[21..22]Right/RPC[1..9]_HV.imon"));
198     a->Add(new TObjString("MTR_INSIDE_MT[11..12]Right/RPC[1..9]_HV.imon"));
199     a->Add(new TObjString("MTR_INSIDE_MT[21..22]Right/RPC[1..9]_HV.imon"));
200
201     a->Add(new TObjString("MTR_OUTSIDE_MT[11..12]Right/RPC[1..9]_HV.vmon"));
202     a->Add(new TObjString("MTR_OUTSIDE_MT[21..22]Right/RPC[1..9]_HV.vmon"));
203     a->Add(new TObjString("MTR_INSIDE_MT[11..12]Right/RPC[1..9]_HV.vmon"));
204     a->Add(new TObjString("MTR_INSIDE_MT[21..22]Right/RPC[1..9]_HV.vmon"));
205   }
206   
207
208   if(fDetector == kTrackerDet){
209     // St345 (DCS Switches)
210     AliMpDEIterator it;
211   
212     it.First();
213   
214     while (!it.IsDone())
215     {
216       Int_t detElemId = it.CurrentDEId();
217       if ( AliMpDEManager::GetStationType(detElemId) == AliMp::kStation345 )
218       {
219         a->Add(new TObjString(Form("MchDE%04dsw[0..%d].inValue",detElemId,NumberOfPCBs(detElemId)-1)));
220       }
221       it.Next();
222     }
223   }
224   
225   return a;
226 }
227
228 //_____________________________________________________________________________
229 Int_t 
230 AliMpDCSNamer::DCS2DE(Int_t chId, Int_t side, Int_t dcsNumber) const
231 {
232   /// Convert DCS Tracker "slat number" (old convention) to DE (new) convention.
233   ///
234   /// \param chamberId : chamber number (starting at 0)
235   /// \param side : 0 for Left, 1 for Right
236   /// \param dcsNumber : slat number in DCS convention
237   ///
238   /// note that dcsNumber should be >=0 and < number of DEs/2 in chamber
239
240   Int_t de(-1);
241   Int_t chamberId = chId;
242
243   if(fDetector == kTrackerDet){ // Tracker
244
245     Int_t nofDE = AliMpDEManager::GetNofDEInChamber(chamberId);
246   
247     Int_t half = nofDE/2;
248   
249     dcsNumber = half - dcsNumber;
250   
251     Int_t quarter = nofDE/4;
252     Int_t threeQuarter = half + quarter;
253   
254     if ( side == 0 ) // left
255     {
256       de = threeQuarter + 1 - dcsNumber;
257     }
258     else if ( side == 1 ) // right
259     {
260       if ( dcsNumber <= quarter )
261       {
262         de = dcsNumber + threeQuarter;
263       }
264       else
265       {
266         de = dcsNumber - quarter - 1;
267       }
268     }
269   }
270   else { // Trigger
271
272     if ( chId < 19 ) chamberId = chId - 1;
273     else chamberId = chId - 9;
274
275     Int_t nofDE = AliMpDEManager::GetNofDEInChamber(chamberId);
276
277     if ( side == 0 ) // left -> Outside
278     {
279       de = 14 - dcsNumber;
280     }
281     else if ( side == 1 ) // right -> Inside
282     {
283       if (nofDE>0)
284         de = (13 + dcsNumber) % nofDE;
285     }
286   }
287   
288   return (chamberId+1)*100 + de;
289 }
290
291
292 //_____________________________________________________________________________
293 Int_t
294 AliMpDCSNamer::DetElemId2DCS(Int_t detElemId, Int_t& side, Int_t &chId) const
295 {
296   /// Convert DE to DCS "slat number"
297   /// @see DCS2DE
298
299   CheckConsistency(detElemId);
300   
301   Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
302   if ( chamberId < 0 ) 
303   {
304     AliDebug(1,Form("DetElemId %d invalid",detElemId));
305     return -1;
306   }
307   Int_t dcsNumber = (detElemId-(chamberId+1)*100);
308
309   switch ( AliMpDEManager::GetStationType(detElemId) )
310   {
311     case AliMp::kStation12:
312     {
313       switch (dcsNumber)
314       {
315         case 0:
316         case 3:
317           side = 1; // right
318           break;
319         case 1:
320         case 2:
321           side = 0; // left
322         default:
323           break;
324       }
325     }
326       break;
327     case AliMp::kStation345:
328     {
329       Int_t nofDE = AliMpDEManager::GetNofDEInChamber(chamberId);
330       
331       Int_t quarter = nofDE/4;
332       
333       Int_t half = nofDE/2;
334       
335       Int_t threeQuarter = half + quarter;  
336       
337       side = -1;
338       
339       if ( dcsNumber <= quarter ) 
340       {
341         dcsNumber += quarter + 1 ;
342         side = 1; // right
343       }
344       else if ( dcsNumber <= threeQuarter )
345       {
346         dcsNumber = ( threeQuarter - dcsNumber + 1 );
347         side = 0; // left
348       }
349       else if ( dcsNumber > threeQuarter ) 
350       {
351         dcsNumber = dcsNumber - threeQuarter;
352         side = 1; // right
353       }
354       else
355       {
356         AliFatal("oups");
357       }  
358       // dcs convention change : numbering from top, not from bottom
359       dcsNumber = half-dcsNumber;
360     }
361       break;
362     case AliMp::kStationTrigger:
363     {
364       if (chamberId < AliMpConstants::NofChambers()-2)
365         chId = chamberId + 1;
366       else chId = 23 + chamberId - AliMpConstants::NofChambers();
367
368       Int_t nofDE = AliMpDEManager::GetNofDEInChamber(chamberId);
369
370       if ( dcsNumber >=5 && dcsNumber <= 13 ) {
371         side = 0;
372         dcsNumber = 14 - dcsNumber;
373       }
374       else {
375         side = 1;
376         if (nofDE>0)
377           dcsNumber = (5 + dcsNumber) % nofDE;
378       }
379       AliDebug(10, Form("detElemId %i  -> MT%i_side%i_L%i", detElemId, chId, side, dcsNumber));
380     }
381       break;
382     default:
383       break;
384   }
385
386   return dcsNumber;
387 }
388
389 //_____________________________________________________________________________
390 TString
391 AliMpDCSNamer::DCSNameFromAlias(const char* dcsAlias) const
392 {
393   /// Convert a (possibly partial) aliasname to a name (only for MCH)
394   
395   TString salias(dcsAlias);
396   
397   if ( !salias.Contains("MchHvLv") ) return dcsAlias;
398   
399   Int_t quadrantNumber(-1);
400   Int_t chamberNumber(-1);
401   Int_t side(-1);
402   
403   if ( salias.Contains("Left")) side = 0;
404   if ( salias.Contains("Right")) side = 1;
405   
406   if ( side < 0 ) return "";
407   
408   TString channelName;
409   
410   if ( salias.Contains("Slat") )
411   {
412     Int_t slatNumber(-1);
413     sscanf(salias.Data(),fgkDCSChannelSt345Pattern[side],&chamberNumber,&slatNumber);
414     ++chamberNumber;
415     ++slatNumber;
416     channelName = TString::Format(fgkDCSChannelSt345Pattern[side],chamberNumber,slatNumber);
417   }
418   else if ( salias.Contains("Sect") )
419   {
420     Int_t sectorNumber(-1);
421     sscanf(salias.Data(),fgkDCSChannelSt12Pattern[side],&chamberNumber,&quadrantNumber,&sectorNumber);
422     ++chamberNumber;
423     ++quadrantNumber;
424     ++sectorNumber;
425     channelName =  TString::Format(fgkDCSChannelSt12Pattern[side],chamberNumber,quadrantNumber,sectorNumber);
426   }
427   else if ( salias.Contains("Quad") )
428   {
429     sscanf(salias.Data(),fgkDCSQuadrantPattern[side],&chamberNumber,&quadrantNumber);
430     ++chamberNumber;
431     ++quadrantNumber;
432     channelName =  TString::Format(fgkDCSQuadrantPattern[side],chamberNumber,quadrantNumber);
433   }
434   else if ( salias.Contains("Chamber") )
435   {
436     sscanf(salias.Data(),fgkDCSChamberPattern[side],&chamberNumber);
437     ++chamberNumber;
438     channelName =  TString::Format(fgkDCSChamberPattern[side],chamberNumber);
439   }
440
441   if ( TString(dcsAlias).Contains("iMon") )
442   {
443     channelName.ReplaceAll("vMon","iMon");
444   }
445   
446   return channelName;
447 }
448
449 //_____________________________________________________________________________
450 TString
451 AliMpDCSNamer::DCSAliasFromName(const char* dcsName) const
452 {
453   /// Convert a (possibly partial) dcsname to an alias (only for MCH)
454   
455   TString sname(dcsName);
456   
457   if ( !sname.Contains("MchHvLv") ) return dcsName;
458   
459   Int_t quadrantNumber(-1);
460   Int_t chamberNumber(-1);
461   Int_t side(-1);
462   
463   if ( sname.Contains("Left")) side = 0;
464   if ( sname.Contains("Right")) side = 1;
465   
466   if ( side < 0 ) return "";
467   
468   TString channelName;
469   
470   if ( sname.Contains("Slat") )
471   {
472     Int_t slatNumber(-1);
473     sscanf(sname.Data(),fgkDCSChannelSt345Pattern[side],&chamberNumber,&slatNumber);
474     --chamberNumber;
475     --slatNumber;
476     channelName = TString::Format(fgkDCSChannelSt345Pattern[side],chamberNumber,slatNumber);
477   }
478   else if ( sname.Contains("Sect") )
479   {
480     Int_t sectorNumber(-1);
481     sscanf(sname.Data(),fgkDCSChannelSt12Pattern[side],&chamberNumber,&quadrantNumber,&sectorNumber);
482     --chamberNumber;
483     --quadrantNumber;
484     --sectorNumber;
485     channelName =  TString::Format(fgkDCSChannelSt12Pattern[side],chamberNumber,quadrantNumber,sectorNumber);
486   }
487   else if ( sname.Contains("Quad") )
488   {
489     sscanf(sname.Data(),fgkDCSQuadrantPattern[side],&chamberNumber,&quadrantNumber);
490     --chamberNumber;
491     --quadrantNumber;
492     channelName =  TString::Format(fgkDCSQuadrantPattern[side],chamberNumber,quadrantNumber);
493   }
494   else if ( sname.Contains("Chamber") )
495   {
496     sscanf(sname.Data(),fgkDCSChamberPattern[side],&chamberNumber);
497     --chamberNumber;
498     channelName =  TString::Format(fgkDCSChamberPattern[side],chamberNumber);
499   }
500   
501   if ( TString(dcsName).Contains("iMon") )
502   {
503     channelName.ReplaceAll("vMon","iMon");
504   }
505   
506   return channelName;
507 }
508
509 //_____________________________________________________________________________
510 TString
511 AliMpDCSNamer::DCSAliasName(Int_t detElemId, Int_t sector, Int_t dcsMeasure) const
512 {
513   /// Return the alias name of the DCS Channel for a given DCS area
514   /// \param detElemId
515   /// \param sector = 0,1 or 2 for St12, and is unused for st345 and trigger
516   /// \param dcsMeasure = kDCSHV, kDCSI
517   
518   Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
519   if ( chamberId < 0 ) return "";
520   
521   Int_t side(-1), chId(-1);
522   Int_t dcsNumber = DetElemId2DCS(detElemId,side,chId);
523   
524   TString aliasName;
525   
526   switch (AliMpDEManager::GetStationType(detElemId))
527   {
528     case AliMp::kStation12:
529       aliasName.Form(fgkDCSChannelSt12Pattern[side],chamberId,dcsNumber,sector);
530       break;
531     case AliMp::kStation345:
532       aliasName.Form(fgkDCSChannelSt345Pattern[side],chamberId,dcsNumber);
533       break;
534     case AliMp::kStationTrigger:
535       return TString::Format(fgkDCSChannelTriggerPattern[side],fgkDCSSideTriggerName[side],chId,dcsNumber,fgkDCSMeasureName[dcsMeasure]);
536       break;
537     default:
538       return "";
539       break;
540   }
541   
542   if ( dcsMeasure == AliMpDCSNamer::kDCSI )
543   {
544     aliasName.ReplaceAll("vMon","iMon");
545   }
546   
547   return aliasName;
548   
549 }
550
551 //_____________________________________________________________________________
552 TString
553 AliMpDCSNamer::DCSSwitchAliasName(Int_t detElemId, Int_t pcbNumber) const
554 {
555   /// Return the alias name of the DCS Switch for a given PCB 
556   /// within a slat of St345
557   
558   if (AliMpDEManager::GetStationType(detElemId) == AliMp::kStation345)
559   {
560     return TString::Format(fgkDCSSwitchSt345Pattern,detElemId,pcbNumber);
561   }
562   return "";
563 }
564
565 //_____________________________________________________________________________
566 Int_t 
567 AliMpDCSNamer::DCSIndexFromDCSAlias(const char* dcsAlias) const
568 {
569   /// Converts the dcs alias to a hv index 
570   ///
571   /// dcsAlias has one of the following 3 forms :
572   ///
573   /// MchHvLv[Left|Right]/Chamber##[Left|Right]/Chamber##[Left|Right]Slat##.actual.vMon
574   ///
575   /// MchHvLv[Left|Right]/Chamber##[Left|Right]/Chamber##[Left|Right]Quad#Sect#.actual.vMon
576   ///
577   /// MchDE####dsw#.inValue
578   
579   TString sDcsAlias(dcsAlias);
580   Int_t de(-1);
581   Int_t sw(-1);
582   
583   int side(-1);
584   
585   if ( sDcsAlias.Contains("Left") )
586   {
587     side = 0;
588   }
589   else if ( sDcsAlias.Contains("Right") )
590   {
591     side = 1;
592   }
593   else
594   {
595     /// it's a switch
596     sscanf(sDcsAlias.Data(),fgkDCSSwitchSt345Pattern,&de,&sw);
597     return sw;
598   }
599   
600   int n1(-1);
601   int n3(-1);
602   int n4(-1);
603   
604   if ( sDcsAlias.Contains("Quad") )
605   {
606     sscanf(sDcsAlias.Data(),fgkDCSChannelSt12Pattern[side],&n1,&n3,&n4);    
607     return n4;
608   }
609   
610   return -2;
611 }
612
613 //_____________________________________________________________________________
614 Int_t 
615 AliMpDCSNamer::DetElemIdFromDCSAlias(const char* dcsAlias) const
616 {
617   /// Converts the dcs alias to a detection element identifier
618   ///
619   /// dcsAlias has one of the following forms :
620   ///
621   /// MchHvLv[Left|Right]/Chamber##[Left|Right]/Chamber##[Left|Right]Slat##.actual.vMon
622   ///
623   /// MchHvLv[Left|Right]/Chamber##[Left|Right]/Chamber##[Left|Right]Quad#Sect#.actual.vMon
624   ///
625   /// MTR_Side[OUTSIDE|INSIDE]_MTChamber##_RPC#_HV.Type[actual.iMon|vEff]
626   
627   AliDebug(1,Form("dcsAlias=%s",dcsAlias));
628   
629   TString sDcsAlias(dcsAlias);
630   
631   int side(-1);
632
633   const char** sideName = (fDetector == kTriggerDet) ? fgkDCSSideTriggerName : fgkDCSSideTrackerName;
634
635   for(Int_t iside=0; iside<2; iside++){
636     if ( sDcsAlias.Contains(sideName[iside]) ) {
637       side = iside;
638       break;
639     }
640   }
641   if(side<0) return -2;
642   
643   int n1(-1);
644   int n3(-1);
645   int n4(-1);
646   char type[15];
647   char cside[4];
648   int detElemId(-1);
649   
650   if ( sDcsAlias.Contains("Slat") )
651   {
652     sscanf(sDcsAlias.Data(),fgkDCSChannelSt345Pattern[side],&n1,&n3);
653     detElemId = DCS2DE(n1,side,n3);
654     AliDebug(1,Form("Slat side=%d n1=%d n3=%d de=%d",side,n1,n3,detElemId));
655   }
656   else if ( sDcsAlias.Contains("Quad") )
657   {
658     sscanf(sDcsAlias.Data(),fgkDCSChannelSt12Pattern[side],&n1,&n3,&n4);    
659     detElemId = 100*(n1+1) + n3;
660     AliDebug(1,Form("Quad side=%d n1=%d n3=%d n4=%d de=%d",side,n1,n3,n4,detElemId));
661   }
662   else if ( sDcsAlias.Contains("MT") )
663   {
664     sscanf(sDcsAlias.Data(),fgkDCSChannelTriggerPatternRead[side],cside,&n1,&n3,type);
665     detElemId = DCS2DE(n1,side,n3);
666     AliDebug(1,Form("Slat side=%d n1=%d n3=%d de=%d",side,n1,n3,detElemId));
667   }
668   else
669   {
670     return -3;
671   }
672   
673   if ( !AliMpDEManager::IsValidDetElemId(detElemId)  )
674   {
675     AliError(Form("Invalid aliasName %s",dcsAlias));
676     return -1;
677   }
678   
679   return detElemId;
680 }
681
682 //_____________________________________________________________________________
683 Int_t AliMpDCSNamer::DCSvariableFromDCSAlias(const char* dcsAlias) const
684 {
685   /// Get DCS variable from an alias (trigger)
686   
687   TString sDcsAlias(dcsAlias);
688
689   Int_t dcsMeasurement = -1;
690
691   for(Int_t iMeas=0; iMeas<kNDCSMeas; iMeas++){
692     if ( sDcsAlias.Contains(fgkDCSMeasureName[iMeas]) ) {
693       dcsMeasurement = iMeas;
694       break;
695     }
696   }
697
698   return dcsMeasurement;
699 }
700
701
702 //_____________________________________________________________________________
703 TObjArray*
704 AliMpDCSNamer::GenerateAliases() const
705 {
706   /// Generate DCS alias names, for MUON Tracker High Voltage system.
707   /// or for MUON Trigger HV and current system.
708   ///
709   /// We first generate aliases of DCS channels :
710   ///
711   /// St 1 ch  1 : 12 channels
712   ///      ch  2 : 12 channels 
713   /// St 2 ch  3 : 12 channels
714   ///      ch  4 : 12 channels
715   /// St 3 ch  5 : 18 channels
716   ///      ch  6 : 18 channels
717   /// St 4 ch  7 : 26 channels
718   ///      ch  8 : 26 channels
719   /// St 5 ch  9 : 26 channels
720   ///      ch 10 : 26 channels
721   ///
722   /// then aliases of DCS switches (only for St345) : 1 switch per PCB.
723   ///
724   /// Returns a TObjArray of TObjString(=alias name)
725   
726   TObjArray* aliases = new TObjArray;
727   aliases->SetOwner(kTRUE);
728   
729   Int_t nMeasures = (fDetector == kTriggerDet) ? kNDCSMeas : 1;
730   
731   for(Int_t iMeas=0; iMeas<nMeasures; iMeas++){
732     
733     AliMpDEIterator it;
734     
735     it.First();
736     
737     while (!it.IsDone())
738     {
739       Int_t detElemId = it.CurrentDEId();
740       switch (fDetector){
741         case kTrackerDet:
742         {
743           switch ( AliMpDEManager::GetStationType(detElemId) )
744           {
745             case AliMp::kStation12:
746               for ( int sector = 0; sector < 3; ++sector)
747               {
748                 aliases->Add(new TObjString(DCSAliasName(detElemId,sector)));
749                 aliases->Add(new TObjString(DCSAliasName(detElemId,sector,AliMpDCSNamer::kDCSI)));
750               }
751               break;
752             case AliMp::kStation345:
753               aliases->Add(new TObjString(DCSAliasName(detElemId)));
754               aliases->Add(new TObjString(DCSAliasName(detElemId,0,AliMpDCSNamer::kDCSI)));
755               for ( Int_t i = 0; i < NumberOfPCBs(detElemId); ++i )
756               {
757                 aliases->Add(new TObjString(DCSSwitchAliasName(detElemId,i)));
758               }
759               break;
760             default:
761               break;
762           }
763         }
764           break;
765         case kTriggerDet:
766         {
767           switch ( AliMpDEManager::GetStationType(detElemId) )
768           {
769             case AliMp::kStationTrigger:
770               AliDebug(10,Form("Current DetElemId %i",detElemId));
771               aliases->Add(new TObjString(DCSAliasName(detElemId,0,iMeas)));
772               break;
773             default:
774               break;
775           }
776         }
777           break;
778       }
779       it.Next();
780     } // loop on detElemId
781   } // Loop on measurement type
782   
783   return aliases;
784 }
785
786 //_____________________________________________________________________________
787 Int_t 
788 AliMpDCSNamer::ManuId2Index(Int_t detElemId, Int_t manuId) const
789 {
790   /// Convert (de,manu) to hv index, depending on the station
791   
792   AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
793   if ( stationType == AliMp::kStation345 ) 
794   {
795     return ManuId2PCBIndex(detElemId,manuId);
796   }
797   else if ( stationType == AliMp::kStation12 ) 
798   {
799     return ManuId2Sector(detElemId,manuId);
800   }
801   return -1;
802 }
803
804 //_____________________________________________________________________________
805 Int_t 
806 AliMpDCSNamer::ManuId2PCBIndex(Int_t detElemId, Int_t manuId) const
807 {
808   /// Returns the index of PCB (within a St345 slat) for a given manu number.
809   /// Returns -1 if (detElemId,manuId) is incorrect
810   
811   AliCodeTimerAuto("",0)
812   
813   const AliMpSlat* slat 
814     = AliMpSegmentation::Instance()->GetSlatByElectronics(detElemId, manuId);
815   if ( ! slat ) return -1;
816   
817   return slat->FindPCBIndexByMotifPositionID(manuId);
818 }
819
820 //_____________________________________________________________________________
821 Int_t 
822 AliMpDCSNamer::ManuId2Sector(Int_t detElemId, Int_t manuId) const
823 {
824   /// Return the DCS-sector number (within a St12 quadrant) for a given manu number.
825   
826   AliCodeTimerAuto("",0)
827   
828   const AliMpSector* sector 
829     = AliMpSegmentation::Instance()->GetSectorByElectronics(detElemId, manuId);
830   if ( ! sector ) return -1;
831   
832   const AliMpMotifMap* motifMap = sector->GetMotifMap();
833   const AliMpMotifPosition* motifPos = motifMap->FindMotifPosition(manuId);
834
835   Double_t lowerLeftX 
836     = motifPos->GetPositionX()-motifPos->GetDimensionX();
837   
838   Double_t x = lowerLeftX*10.0; // cm -> mm
839   Int_t isector(-1);
840
841   AliMq::Station12Type stationType = AliMpDEManager::GetStation12Type(detElemId);
842   
843   if ( stationType == AliMq::kStation1 ) 
844   {
845     if ( x < -10 ) AliFatal("");
846     
847     if ( x < 291.65 ) isector = 0;
848     else if ( x < 585.65 ) isector = 1;
849     else if ( x < 879.65 ) isector = 2;
850   }
851   else
852   {
853     if ( x < -140 ) AliFatal("");
854     
855     if ( x < 283.75 ) isector = 0;
856     else if ( x < 606.25 ) isector = 1;
857     else if ( x < 1158.75 ) isector = 2;
858   }
859   
860   return isector;
861 }
862
863 //_____________________________________________________________________________
864 Int_t 
865 AliMpDCSNamer::NumberOfPCBs(Int_t detElemId) const
866 {
867   /// Returns the number of PCB in a given detection element
868   /// Only works for St345
869   
870   AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
871   if ( stationType != AliMp::kStation345 )
872   {
873     return 0;
874   }
875   else
876   {
877     const AliMpSlat* slat 
878       = AliMpSegmentation::Instance()->GetSlat(detElemId, AliMp::kCath0);
879     return slat->GetSize();
880   }
881 }
882
883 //_____________________________________________________________________________
884 Bool_t AliMpDCSNamer::CheckConsistency(Int_t detElemId) const
885 {
886   //
887   /// Check that the required detElemId either belongs to tracker or trigger
888   /// consistently with the initial definition of the namer
889   //
890
891   Bool_t isConsistent(kFALSE);
892   TString requestInfo;
893   switch(AliMpDEManager::GetStationType(detElemId))
894   {
895   case AliMp::kStation12:
896   case AliMp::kStation345:
897     if (fDetector == kTrackerDet) isConsistent = kTRUE;
898     requestInfo = "TRACKER";
899     break;
900   case AliMp::kStationTrigger:
901     if (fDetector == kTriggerDet) isConsistent = kTRUE;
902     requestInfo = "TRIGGER";
903     break;
904   default:
905     break;
906   }
907
908   if(!isConsistent) AliWarning(Form("Requesting information for %s station but class initialized for %s",requestInfo.Data(), fgkDetectorName[fDetector]));
909
910   return isConsistent;
911 }