Initial version (Laurent)
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpHVNamer.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 "AliMpHVNamer.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 "AliMpSectorSegmentation.h"
30 #include "AliMpSegmentation.h"
31 #include "AliMpSlat.h"
32 #include "AliMpSlatSegmentation.h"
33 #include <Riostream.h>
34 #include <TMap.h>
35 #include <TObjArray.h>
36 #include <TObjString.h>
37 #include <TString.h>
38 #include <TSystem.h>
39
40 //-----------------------------------------------------------------------------
41 /// \class AliMpHVNamer
42 /// 
43 /// A utility class to manage HV DCS aliases names, in particular the
44 /// two conventions used to number the detection elements within a detector.
45 ///
46 /// \author: Laurent Aphecetche, Subatech
47 //-----------------------------------------------------------------------------
48
49 /// \cond CLASSIMP
50 ClassImp(AliMpHVNamer)
51 /// \endcond
52
53 const char* AliMpHVNamer::fgHVChannelSt345Pattern[] = 
54 { "MchHvLvLeft/Chamber%02dLeft/Slat%02d.actual.vMon",
55   "MchHvLvRight/Chamber%02dRight/Slat%02d.actual.vMon" 
56 };
57
58 const char* AliMpHVNamer::fgHVChannelSt12Pattern[] = 
59 {
60   "MchHvLvLeft/Chamber%02dLeft/Quad%dSect%d.actual.vMon",
61   "MchHvLvRight/Chamber%02dRight/Quad%dSect%d.actual.vMon",
62 };
63
64 const char* AliMpHVNamer::fgHVSwitchSt345Pattern = "MchDE%04dsw%d.inValue";
65
66 //_____________________________________________________________________________
67 AliMpHVNamer::AliMpHVNamer()
68 {
69  /// default ctor 
70 }
71
72 //_____________________________________________________________________________
73 AliMpHVNamer::~AliMpHVNamer()
74 {
75   /// dtor
76 }
77
78 //_____________________________________________________________________________
79 void 
80 AliMpHVNamer::AliasesAsLdif(const char* ldiffile) const
81 {
82 /// Export the aliases in LDIF format
83
84   ofstream out(ldiffile);
85   
86   TObjArray* a = CompactAliases();
87   
88   TIter next(a);
89   TObjString* s;
90
91   // Some header. host name and port probably not up to date.
92   out << "#MCH config" << endl
93     << "dn: det=MCH,o=alice,dc=cern,dc=ch" << endl
94     << "objectClass: AliShuttleDetector" << endl
95     << "det: MCH" << endl
96     << "StrictRunOrder: 1" << endl
97     << "responsible: aphecetc@in2p3.fr" << endl
98     << "DCSHost: aldcs053.cern.ch" << endl
99     << "DCSPort: 4242" <<endl;
100   
101   while ( ( s = (TObjString*)(next()) ) )
102   {
103     out << "DCSalias: " << s->String().Data() << endl;
104   }
105   
106   out.close();
107   
108   delete a;
109 }
110
111 //_____________________________________________________________________________
112 TObjArray*
113 AliMpHVNamer::CompactAliases() const
114 {
115   /// Generate a compact list of aliases, for Shuttle test
116   /// This one is completely hand-made, in contrast with GenerateAliases()
117   /// method
118
119   TObjArray* a = new TObjArray;
120   a->SetOwner(kTRUE);
121   
122   // St 12 (HV Channels)
123   a->Add(new TObjString("MchHvLvRight/Chamber[00..03]Right/Quad0Sect[0..2].actual.vMon"));
124   a->Add(new TObjString("MchHvLvLeft/Chamber[00..03]Left/Quad1Sect[0..2].actual.vMon"));
125   a->Add(new TObjString("MchHvLvLeft/Chamber[00..03]Left/Quad2Sect[0..2].actual.vMon"));
126   a->Add(new TObjString("MchHvLvRight/Chamber[00..03]Right/Quad3Sect[0..2].actual.vMon"));
127   
128   // St345 (HV Channels)
129   
130   a->Add(new TObjString("MchHvLvRight/Chamber[04..09]Right/Slat[00..08].actual.vMon"));
131   a->Add(new TObjString("MchHvLvLeft/Chamber[04..09]Left/Slat[00..08].actual.vMon"));
132
133   a->Add(new TObjString("MchHvLvRight/Chamber[06..09]Right/Slat[09..12].actual.vMon"));
134   a->Add(new TObjString("MchHvLvLeft/Chamber[06..09]Left/Slat[09..12].actual.vMon"));
135
136   // St345 (HV Switches)
137   AliMpDEIterator it;
138   
139   it.First();
140   
141   while (!it.IsDone())
142   {
143     Int_t detElemId = it.CurrentDEId();
144     if ( AliMpDEManager::GetStationType(detElemId) == AliMp::kStation345 )
145     {
146           a->Add(new TObjString(Form("MchDE%04dsw[0..%d].inValue",detElemId,NumberOfPCBs(detElemId)-1)));
147      }
148     it.Next();
149   }
150   return a;
151 }
152
153 //_____________________________________________________________________________
154 Int_t 
155 AliMpHVNamer::DCS2DE(Int_t chamberId, Int_t side, Int_t dcsNumber) const
156 {
157   /// Convert DCS "slat number" (old convention) to DE (new) convention.
158   ///
159   /// \param chamberId : chamber number (starting at 0)
160   /// \param side : 0 for Left, 1 for Right
161   /// \param dcsNumber : slat number in DCS HV convention
162   ///
163   /// note that dcsNumber should be >=0 and < number of DEs/2 in chamber
164
165   Int_t nofDE = AliMpDEManager::GetNofDEInChamber(chamberId);
166   
167   Int_t half = nofDE/2;
168   
169   dcsNumber = half - dcsNumber;
170   
171   Int_t quarter = nofDE/4;
172   Int_t threeQuarter = half + quarter;
173   
174   Int_t de(-1);
175   
176   if ( side == 0 ) // left
177   {
178     de = threeQuarter + 1 - dcsNumber;
179   }
180   else if ( side == 1 ) // right
181   {
182     if ( dcsNumber <= quarter )
183     {
184       de = dcsNumber + threeQuarter;
185     }
186     else
187     {
188       de = dcsNumber - quarter - 1;
189     }
190   }
191   
192   return chamberId*100 + de;
193 }
194
195 //_____________________________________________________________________________
196 Int_t
197 AliMpHVNamer::DetElemId2DCS(Int_t detElemId, Int_t& side) const
198 {
199   /// Convert DE to DCS "slat number"
200   /// @see DCS2DE
201   
202   Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
203   if ( chamberId < 0 ) 
204   {
205     AliDebug(1,Form("DetElemId %d invalid",detElemId));
206     return -1;
207   }
208   Int_t dcsNumber = (detElemId-(chamberId+1)*100);
209
210   switch ( AliMpDEManager::GetStationType(detElemId) )
211   {
212     case AliMp::kStation1:
213     case AliMp::kStation2:
214     {
215       switch (dcsNumber)
216       {
217         case 0:
218         case 3:
219           side = 1; // right
220           break;
221         case 1:
222         case 2:
223           side = 0; // left
224         default:
225           break;
226       }
227     }
228       break;
229     case AliMp::kStation345:
230     {
231       Int_t nofDE = AliMpDEManager::GetNofDEInChamber(chamberId);
232       
233       Int_t quarter = nofDE/4;
234       
235       Int_t half = nofDE/2;
236       
237       Int_t threeQuarter = half + quarter;  
238       
239       side = -1;
240       
241       if ( dcsNumber <= quarter ) 
242       {
243         dcsNumber += quarter + 1 ;
244         side = 1; // right
245       }
246       else if ( dcsNumber <= threeQuarter )
247       {
248         dcsNumber = ( threeQuarter - dcsNumber + 1 );
249         side = 0; // left
250       }
251       else if ( dcsNumber > threeQuarter ) 
252       {
253         dcsNumber = dcsNumber - threeQuarter;
254         side = 1; // right
255       }
256       else
257       {
258         AliFatal("oups");
259       }  
260       // dcs convention change : numbering from top, not from bottom
261       dcsNumber = half-dcsNumber;
262     }
263       break;
264     default:
265       break;
266   }
267   return dcsNumber;
268 }
269
270 //_____________________________________________________________________________
271 const char* 
272 AliMpHVNamer::DCSHVChannelName(Int_t detElemId, Int_t sector) const
273 {
274   /// Return the alias name of the HV Channel for a given HV area 
275   /// \param detElemId 
276   /// \param sector = 0,1 or 2 for St12, and is unused for st345
277   
278   Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
279   if ( chamberId < 0 ) return 0x0;
280
281   Int_t side(-1);
282   Int_t dcsNumber = DetElemId2DCS(detElemId,side);
283                                   
284   switch (AliMpDEManager::GetStationType(detElemId))
285   {
286     case AliMp::kStation1:
287     case AliMp::kStation2:
288       return Form(fgHVChannelSt12Pattern[side],chamberId,dcsNumber,sector);
289       break;
290     case AliMp::kStation345:
291       return Form(fgHVChannelSt345Pattern[side],chamberId,dcsNumber);
292       break;
293     default:
294       return 0x0;
295       break;
296   }
297 }
298
299 //_____________________________________________________________________________
300 const char* 
301 AliMpHVNamer::DCSHVSwitchName(Int_t detElemId, Int_t pcbNumber) const
302 {
303   /// Return the alias name of the HV Switch for a given PCB 
304   /// within a slat of St345
305   
306   if (AliMpDEManager::GetStationType(detElemId) == AliMp::kStation345)
307   {
308     return Form(fgHVSwitchSt345Pattern,detElemId,pcbNumber);
309   }
310   return 0x0;
311 }
312
313 //_____________________________________________________________________________
314 Int_t 
315 AliMpHVNamer::DetElemIdFromDCSAlias(const char* dcsAlias) const
316 {
317   /// Converts the dcs alias to a detection element identifier
318   ///
319   /// dcsAlias has one of the following 2 forms :
320   ///
321   /// MchHvLv[Left|Right]/Chamber##[Left|Right]/Chamber##[Left|Right]Slat##.actual.vMon
322   ///
323   /// MchHvLv[Left|Right]/Chamber##[Left|Right]/Chamber##[Left|Right]Quad#Sect#.actual.vMon
324   
325   TString sDcsAlias(dcsAlias);
326   
327   int side(-1);
328   
329   if ( sDcsAlias.Contains("Left") )
330   {
331     side = 0;
332   }
333   else if ( sDcsAlias.Contains("Right") )
334   {
335     side = 1;
336   }
337   else
338   {
339     return -2;
340   }
341   
342   int n1(-1);
343   int n3(-1);
344   int n4(-1);
345   int detElemId(-1);
346   
347   if ( sDcsAlias.Contains("Slat") )
348   {
349     sscanf(sDcsAlias.Data(),fgHVChannelSt345Pattern[side],&n1,&n3);
350     detElemId = DCS2DE(n1,side,n3);
351   }
352   else if ( sDcsAlias.Contains("Quad") )
353   {
354     sscanf(sDcsAlias.Data(),fgHVChannelSt12Pattern[side],&n1,&n3,&n4);    
355     detElemId = n3-1;
356   }
357   else
358   {
359     return -3;
360   }
361   
362   if ( !AliMpDEManager::IsValidDetElemId(detElemId)  )
363   {
364     AliError(Form("Invalid aliasName %s",dcsAlias));
365     return -1;
366   }
367   
368   return detElemId;
369 }
370
371 //_____________________________________________________________________________
372 TObjArray*
373 AliMpHVNamer::GenerateAliases() const
374 {
375   /// Generate DCS alias names, for MUON Tracker High Voltage system.
376   ///
377   /// We first generate aliases of HV channels :
378   ///
379   /// St 1 ch  1 : 12 channels
380   ///      ch  2 : 12 channels 
381   /// St 2 ch  3 : 12 channels
382   ///      ch  4 : 12 channels
383   /// St 3 ch  5 : 18 channels
384   ///      ch  6 : 18 channels
385   /// St 4 ch  7 : 26 channels
386   ///      ch  8 : 26 channels
387   /// St 5 ch  9 : 26 channels
388   ///      ch 10 : 26 channels
389   ///
390   /// then aliases of HV switches (only for St345) : 1 switch per PCB.
391   ///
392   /// Returns a TObjArray of TObjString(=alias name)
393   
394   TObjArray* aliases = new TObjArray;
395   aliases->SetOwner(kTRUE);
396   
397   AliMpDEIterator it;
398   
399   it.First();
400   
401   while (!it.IsDone())
402   {
403     Int_t detElemId = it.CurrentDEId();
404     switch ( AliMpDEManager::GetStationType(detElemId) )
405     {
406       case AliMp::kStation1:
407       case AliMp::kStation2:
408         for ( int sector = 0; sector < 3; ++sector)
409         {
410           aliases->Add(new TObjString(DCSHVChannelName(detElemId,sector)));
411         }
412         break;
413       case AliMp::kStation345:
414         aliases->Add(new TObjString(DCSHVChannelName(detElemId)));
415         for ( Int_t i = 0; i < NumberOfPCBs(detElemId); ++i )
416         {
417           aliases->Add(new TObjString(DCSHVSwitchName(detElemId,i)));
418         }
419         break;
420       default:
421         break;
422     }
423     it.Next();
424   }
425   
426   return aliases;
427 }
428
429 //_____________________________________________________________________________
430 Int_t 
431 AliMpHVNamer::ManuId2Index(Int_t detElemId, Int_t manuId) const
432 {
433   /// Convert (de,manu) to hv index, depending on the station
434   
435   AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
436   if ( stationType == AliMp::kStation345 ) 
437   {
438     return ManuId2PCBIndex(detElemId,manuId);
439   }
440   else if ( stationType == AliMp::kStation1 || stationType == AliMp::kStation2 ) 
441   {
442     return ManuId2Sector(detElemId,manuId);
443   }
444   return -1;
445 }
446
447 //_____________________________________________________________________________
448 Int_t 
449 AliMpHVNamer::ManuId2PCBIndex(Int_t detElemId, Int_t manuId) const
450 {
451   /// Returns the index of PCB (within a St345 slat) for a given manu number.
452   /// Returns -1 if (detElemId,manuId) is incorrect
453   
454   AliCodeTimerAuto("")
455   
456   const AliMpSlatSegmentation* seg = static_cast<const AliMpSlatSegmentation*>
457     (AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId,manuId));
458   const AliMpSlat* slat = seg->Slat();
459   
460   return slat->FindPCBIndexByMotifPositionID(manuId);
461 }
462
463 //_____________________________________________________________________________
464 Int_t 
465 AliMpHVNamer::ManuId2Sector(Int_t detElemId, Int_t manuId) const
466 {
467   /// Return the HV-sector number (within a St12 quadrant) for a given manu number.
468   
469   AliCodeTimerAuto("")
470   
471   const AliMpSectorSegmentation* seg = static_cast<const AliMpSectorSegmentation*>
472   (AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId,manuId));
473   const AliMpSector* sector = seg->GetSector();
474   const AliMpMotifMap* motifMap = sector->GetMotifMap();
475   const AliMpMotifPosition* motifPos = motifMap->FindMotifPosition(manuId);
476
477   TVector2 lowerLeft(motifPos->Position()-motifPos->Dimensions());
478   
479   Double_t x = lowerLeft.X();
480   Int_t isector(-1);
481
482   AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
483   
484   if ( stationType == AliMp::kStation1 ) 
485   {
486     if ( x < -1 ) AliFatal("");
487     
488     if ( x < 291.65 ) isector = 0;
489     else if ( x < 585.65 ) isector = 1;
490     else if ( x < 879.65 ) isector = 2;
491   }
492   else
493   {
494     if ( x < -14 ) AliFatal("");
495     
496     if ( x < 283.75 ) isector = 0;
497     else if ( x < 603.75 ) isector = 1;
498     else if ( x < 1158.75 ) isector = 2;
499   }
500   
501   return isector;
502 }
503
504 //_____________________________________________________________________________
505 Int_t 
506 AliMpHVNamer::NumberOfPCBs(Int_t detElemId) const
507 {
508   /// Returns the number of PCB in a given detection element
509   /// Only works for St345
510   
511   AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
512   if ( stationType != AliMp::kStation345 )
513   {
514     return 0;
515   }
516   else
517   {
518     const AliMpSlatSegmentation* seg = static_cast<const AliMpSlatSegmentation*>
519     (AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath0));
520     const AliMpSlat* slat = seg->Slat();
521     return slat->GetSize();
522   }
523 }