Corrected Doxygen warnings:
[u/mrichter/AliRoot.git] / MUON / AliMUONHVNamer.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 "AliMUONHVNamer.h"
19
20 #include "AliMpArea.h"
21 #include "AliMpDEIterator.h"
22 #include "AliMpDEManager.h"
23 #include "AliMpHelper.h"
24 #include "AliMpSegmentation.h"
25 #include "AliMpSlat.h"
26 #include "AliMpSlatSegmentation.h"
27 #include "AliMpVPadIterator.h"
28
29 #include "AliLog.h"
30 #include "Riostream.h"
31 #include "TMap.h"
32 #include "TObjArray.h"
33 #include "TObjString.h"
34 #include "TString.h"
35 #include "TSystem.h"
36
37 /// $Id$
38 ///
39 /// \class AliMUONHVNamer
40 /// 
41 /// A utility class to manage HV DCS aliases names, in particular the
42 /// two conventions used to number the detection elements within a detector.
43 ///
44 /// \author: Laurent Aphecetche, Subatech
45
46 /// \cond CLASSIMP
47 ClassImp(AliMUONHVNamer)
48 /// \endcond
49
50 const char* AliMUONHVNamer::fgHVChannelSt345Pattern[] = 
51 { "MchHvLvLeft/Chamber%02dLeft/Slat%02d.actual.vMon",
52   "MchHvLvRight/Chamber%02dRight/Slat%02d.actual.vMon" 
53 };
54
55 const char* AliMUONHVNamer::fgHVChannelSt12Pattern[] = 
56 {
57   "MchHvLvLeft/Chamber%02dLeft/Quad%dSect%d.actual.vMon",
58   "MchHvLvRight/Chamber%02dRight/Quad%dSect%d.actual.vMon",
59 };
60   
61 const char* AliMUONHVNamer::fgHVSwitchSt345Pattern = "MchDE%dsw%d.inValue";
62
63 //_____________________________________________________________________________
64 AliMUONHVNamer::AliMUONHVNamer()
65 {
66  /// default ctor 
67 }
68
69 //_____________________________________________________________________________
70 AliMUONHVNamer::~AliMUONHVNamer()
71 {
72   /// dtor
73 }
74
75 //_____________________________________________________________________________
76 TObjArray*
77 AliMUONHVNamer::CompactAliases() const
78 {
79   /// Generate a compact list of aliases, for Shuttle test
80   /// This one is completely hand-made, in contrast with GenerateAliases()
81   /// method
82
83   TObjArray* a = new TObjArray;
84   a->SetOwner(kTRUE);
85   
86   // St 12 (HV Channels)
87   a->Add(new TObjString("MchHvLvRight/Chamber[01..04]Right/Quad1Sect[1..3].actual.vMon"));
88   a->Add(new TObjString("MchHvLvLeft/Chamber[01..04]Left/Quad2Sect[1..3].actual.vMon"));
89   a->Add(new TObjString("MchHvLvLeft/Chamber[01..04]Left/Quad3Sect[1..3].actual.vMon"));
90   a->Add(new TObjString("MchHvLvRight/Chamber[01..04]Right/Quad4Sect[1..3].actual.vMon"));
91   
92   // St345 (HV Channels)
93   
94   a->Add(new TObjString("MchHvLvRight/Chamber[05..10]Right/Slat[01..09].actual.vMon"));
95   a->Add(new TObjString("MchHvLvLeft/Chamber[05..10]Left/Slat[01..09].actual.vMon"));
96
97   a->Add(new TObjString("MchHvLvRight/Chamber[07..10]Right/Slat[10..13].actual.vMon"));
98   a->Add(new TObjString("MchHvLvLeft/Chamber[07..10]Left/Slat[10..13].actual.vMon"));
99
100   // St345 (HV Switches)
101   AliMpDEIterator it;
102   
103   it.First();
104   
105   while (!it.IsDone())
106   {
107     Int_t detElemId = it.CurrentDEId();
108     if ( AliMpDEManager::GetStationType(detElemId) == AliMp::kStation345 )
109     {
110           a->Add(new TObjString(Form("MchDE%dsw[1..%d].inValue",detElemId,NumberOfPCBs(detElemId))));
111      }
112     it.Next();
113   }
114   return a;
115 }
116
117 //_____________________________________________________________________________
118 Int_t 
119 AliMUONHVNamer::DCS2DE(Int_t chamberId, Int_t side, Int_t dcsNumber) const
120 {
121   /// Convert DCS "slat number" (old convention) to DE (new) convention.
122   ///
123   /// \param chamberId : chamber number (starting at 1)
124   /// \param side : 0 for Left, 1 for Right
125   /// \param dcsNumber : slat number in DCS HV convention
126   ///
127   /// note that dcsNumber should be >=1 and <= number of DEs/2 in chamber
128
129   Int_t nofDE = AliMpDEManager::GetNofDEInChamber(chamberId);
130   
131   Int_t half = nofDE/2;
132   
133   dcsNumber = half + 1 - dcsNumber;
134   
135   Int_t quarter = nofDE/4;
136   Int_t threeQuarter = half + quarter;
137   
138   Int_t de(-1);
139   
140   if ( side == 0 ) // left
141   {
142     de = threeQuarter + 1 - dcsNumber;
143   }
144   else if ( side == 1 ) // right
145   {
146     if ( dcsNumber <= quarter )
147     {
148       de = dcsNumber + threeQuarter;
149     }
150     else
151     {
152       de = dcsNumber - quarter - 1;
153     }
154   }
155   
156   return chamberId*100 + de;
157 }
158
159 //_____________________________________________________________________________
160 Int_t
161 AliMUONHVNamer::DetElemId2DCS(Int_t detElemId, Int_t& side) const
162 {
163   /// Convert DE to DCS "slat number"
164   /// @see DCS2DE
165   
166   Int_t chamberId = 1 + AliMpDEManager::GetChamberId(detElemId);
167   if ( chamberId < 1 ) 
168   {
169     AliDebug(1,Form("DetElemId %d invalid",detElemId));
170     return -1;
171   }
172   Int_t dcsNumber = (detElemId-chamberId*100);
173
174   switch ( AliMpDEManager::GetStationType(detElemId) )
175   {
176     case AliMp::kStation1:
177     case AliMp::kStation2:
178     {
179       switch (dcsNumber)
180       {
181         case 0:
182         case 3:
183           side = 1; // right
184           ++dcsNumber;
185           break;
186         case 1:
187         case 2:
188           side = 0; // left
189           ++dcsNumber;
190         default:
191           break;
192       }
193     }
194       break;
195     case AliMp::kStation345:
196     {
197       Int_t nofDE = AliMpDEManager::GetNofDEInChamber(chamberId-1);
198       
199       Int_t quarter = nofDE/4;
200       
201       Int_t half = nofDE/2;
202       
203       Int_t threeQuarter = half + quarter;  
204       
205       side = -1;
206       
207       if ( dcsNumber <= quarter ) 
208       {
209         dcsNumber += quarter + 1 ;
210         side = 1; // right
211       }
212       else if ( dcsNumber <= threeQuarter )
213       {
214         dcsNumber = ( threeQuarter - dcsNumber + 1 );
215         side = 0; // left
216       }
217       else if ( dcsNumber > threeQuarter ) 
218       {
219         dcsNumber = dcsNumber - threeQuarter;
220         side = 1; // right
221       }
222       else
223       {
224         AliFatal("oups");
225       }  
226       // dcs convention change : numbering from top, not from bottom
227       dcsNumber = half+1-dcsNumber;
228     }
229       break;
230     default:
231       break;
232   }
233   return dcsNumber;
234 }
235
236 //_____________________________________________________________________________
237 const char* 
238 AliMUONHVNamer::DCSHVChannelName(Int_t detElemId, Int_t sector) const
239 {
240   /// Return the alias name of the HV Channel for a given HV area 
241   /// \param detElemId 
242   /// \param sector = 0,1 or 2 for St12, and is unused for st345
243   
244   Int_t chamberId = 1 + AliMpDEManager::GetChamberId(detElemId);
245   if ( chamberId < 1 ) return 0x0;
246
247   Int_t side(-1);
248   Int_t dcsNumber = DetElemId2DCS(detElemId,side);
249                                   
250   switch (AliMpDEManager::GetStationType(detElemId))
251   {
252     case AliMp::kStation1:
253     case AliMp::kStation2:
254       return Form(fgHVChannelSt12Pattern[side],chamberId,dcsNumber,sector+1);
255       break;
256     case AliMp::kStation345:
257       return Form(fgHVChannelSt345Pattern[side],chamberId,dcsNumber);
258       break;
259     default:
260       return 0x0;
261       break;
262   }
263 }
264
265 //_____________________________________________________________________________
266 const char* 
267 AliMUONHVNamer::DCSHVSwitchName(Int_t detElemId, Int_t pcbNumber) const
268 {
269   /// Return the alias name of the HV Switch for a given PCB 
270   /// within a slat of St345
271   
272   if (AliMpDEManager::GetStationType(detElemId) == AliMp::kStation345)
273   {
274     return Form(fgHVSwitchSt345Pattern,detElemId,pcbNumber+1);
275   }
276   return 0x0;
277 }
278
279 //_____________________________________________________________________________
280 Int_t 
281 AliMUONHVNamer::DetElemIdFromDCSAlias(const char* dcsAlias) const
282 {
283   /// Converts the dcs alias to a detection element identifier
284   ///
285   /// dcsAlias has one of the following 2 forms :
286   ///
287   /// MchHvLv[Left|Right]/Chamber##[Left|Right]/Chamber##[Left|Right]Slat##.actual.vMon
288   ///
289   /// MchHvLv[Left|Right]/Chamber##[Left|Right]/Chamber##[Left|Right]Quad#Sect#.actual.vMon
290   
291   TString sDcsAlias(dcsAlias);
292   
293   int side(-1);
294   
295   if ( sDcsAlias.Contains("Left") )
296   {
297     side = 0;
298   }
299   else if ( sDcsAlias.Contains("Right") )
300   {
301     side = 1;
302   }
303   else
304   {
305     return -2;
306   }
307   
308   int n1(-1);
309   int n3(-1);
310   int n4(-1);
311   int detElemId(-1);
312   
313   if ( sDcsAlias.Contains("Slat") )
314   {
315     sscanf(sDcsAlias.Data(),fgHVChannelSt345Pattern[side],&n1,&n3);
316     detElemId = DCS2DE(n1,side,n3);
317   }
318   else if ( sDcsAlias.Contains("Quad") )
319   {
320     sscanf(sDcsAlias.Data(),fgHVChannelSt12Pattern[side],&n1,&n3,&n4);    
321     detElemId = n3-1;
322   }
323   else
324   {
325     return -3;
326   }
327   
328   if ( !AliMpDEManager::IsValidDetElemId(detElemId)  )
329   {
330     AliError(Form("Invalid aliasName %s",dcsAlias));
331     return -1;
332   }
333   
334   return detElemId;
335 }
336
337 //_____________________________________________________________________________
338 TObjArray*
339 AliMUONHVNamer::GenerateAliases() const
340 {
341   /// Generate DCS alias names, for MUON Tracker High Voltage system.
342   ///
343   /// We first generate aliases of HV channels :
344   ///
345   /// St 1 ch  1 : 12 channels
346   ///      ch  2 : 12 channels 
347   /// St 2 ch  3 : 12 channels
348   ///      ch  4 : 12 channels
349   /// St 3 ch  5 : 18 channels
350   ///      ch  6 : 18 channels
351   /// St 4 ch  7 : 26 channels
352   ///      ch  8 : 26 channels
353   /// St 5 ch  9 : 26 channels
354   ///      ch 10 : 26 channels
355   ///
356   /// then aliases of HV switches (only for St345) : 1 switch per PCB.
357   ///
358   /// Returns a TObjArray of TObjString(=alias name)
359   
360   TObjArray* aliases = new TObjArray;
361   aliases->SetOwner(kTRUE);
362   
363   AliMpDEIterator it;
364   
365   it.First();
366   
367   while (!it.IsDone())
368   {
369     Int_t detElemId = it.CurrentDEId();
370     switch ( AliMpDEManager::GetStationType(detElemId) )
371     {
372       case AliMp::kStation1:
373       case AliMp::kStation2:
374         for ( int sector = 0; sector < 3; ++sector)
375         {
376           aliases->Add(new TObjString(DCSHVChannelName(detElemId,sector)));
377         }
378         break;
379       case AliMp::kStation345:
380         aliases->Add(new TObjString(DCSHVChannelName(detElemId)));
381         for ( Int_t i = 0; i < NumberOfPCBs(detElemId); ++i )
382         {
383           aliases->Add(new TObjString(DCSHVSwitchName(detElemId,i)));
384         }
385         break;
386       default:
387         break;
388     }
389     it.Next();
390   }
391   
392   return aliases;
393 }
394
395 //_____________________________________________________________________________
396 Int_t 
397 AliMUONHVNamer::ManuId2PCBIndex(Int_t detElemId, Int_t manuId) const
398 {
399   /// Returns the index of PCB (within a St345 slat) for a given manu number.
400   /// Returns -1 if (detElemId,manuId) is incorrect
401   
402   const AliMpSlatSegmentation* seg = static_cast<const AliMpSlatSegmentation*>
403     (AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId,manuId));
404   const AliMpSlat* slat = seg->Slat();
405   AliMpVPadIterator* it = seg->CreateIterator();
406   it->First();
407   AliMpPad pad = it->CurrentItem();
408   
409   while ( !it->IsDone() && pad.GetLocation().GetFirst() != manuId ) 
410   {
411     it->Next();
412     pad = it->CurrentItem();
413   }
414   
415   Int_t pcbIndex = slat->FindPCBIndex(pad.Position().X()+slat->Position().X(),
416                                       pad.Position().Y()+slat->Position().Y());
417 //  AliDebug(1,Form("pcbIndex %d",pcbIndex));
418 //  StdoutToAliDebug(1,pad.Print());
419   return pcbIndex;
420 }
421
422 //_____________________________________________________________________________
423 Int_t 
424 AliMUONHVNamer::ManuId2Sector(Int_t /*detElemId*/, Int_t /*manuId*/) const
425 {
426   /// Return the HV-sector number (within a St12 quadrant) for a given manu number.
427   
428   //FIXME: write me !
429   return 0;
430 }
431
432 //_____________________________________________________________________________
433 Int_t 
434 AliMUONHVNamer::NumberOfPCBs(Int_t detElemId) const
435 {
436   /// Returns the number of PCB in a given detection element
437   /// Only works for St345
438   
439   AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
440   if ( stationType != AliMp::kStation345 )
441   {
442     return 0;
443   }
444   else
445   {
446     const AliMpSlatSegmentation* seg = static_cast<const AliMpSlatSegmentation*>
447     (AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath0));
448     const AliMpSlat* slat = seg->Slat();
449     return slat->GetSize();
450   }
451 }