1 /**************************************************************************
2 * Copyright(c) 1998-1999, 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 #include "AliMpHVNamer.h"
20 #include "AliCodeTimer.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>
35 #include <TObjArray.h>
36 #include <TObjString.h>
40 //-----------------------------------------------------------------------------
41 /// \class AliMpHVNamer
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.
46 /// \author: Laurent Aphecetche, Subatech
47 //-----------------------------------------------------------------------------
50 ClassImp(AliMpHVNamer)
53 const char* AliMpHVNamer::fgHVChannelSt345Pattern[] =
54 { "MchHvLvLeft/Chamber%02dLeft/Slat%02d.actual.vMon",
55 "MchHvLvRight/Chamber%02dRight/Slat%02d.actual.vMon"
58 const char* AliMpHVNamer::fgHVChannelSt12Pattern[] =
60 "MchHvLvLeft/Chamber%02dLeft/Quad%dSect%d.actual.vMon",
61 "MchHvLvRight/Chamber%02dRight/Quad%dSect%d.actual.vMon",
64 const char* AliMpHVNamer::fgHVSwitchSt345Pattern = "MchDE%04dsw%d.inValue";
66 //_____________________________________________________________________________
67 AliMpHVNamer::AliMpHVNamer()
72 //_____________________________________________________________________________
73 AliMpHVNamer::~AliMpHVNamer()
78 //_____________________________________________________________________________
80 AliMpHVNamer::AliasesAsLdif(const char* ldiffile) const
82 /// Export the aliases in LDIF format
84 ofstream out(ldiffile);
86 TObjArray* a = CompactAliases();
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
96 << "StrictRunOrder: 1" << endl
97 << "responsible: aphecetc@in2p3.fr" << endl
98 << "DCSHost: aldcs053.cern.ch" << endl
99 << "DCSPort: 4242" <<endl;
101 while ( ( s = (TObjString*)(next()) ) )
103 out << "DCSalias: " << s->String().Data() << endl;
111 //_____________________________________________________________________________
113 AliMpHVNamer::CompactAliases() const
115 /// Generate a compact list of aliases, for Shuttle test
116 /// This one is completely hand-made, in contrast with GenerateAliases()
119 TObjArray* a = new TObjArray;
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"));
128 // St345 (HV Channels)
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"));
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"));
136 // St345 (HV Switches)
143 Int_t detElemId = it.CurrentDEId();
144 if ( AliMpDEManager::GetStationType(detElemId) == AliMp::kStation345 )
146 a->Add(new TObjString(Form("MchDE%04dsw[0..%d].inValue",detElemId,NumberOfPCBs(detElemId)-1)));
153 //_____________________________________________________________________________
155 AliMpHVNamer::DCS2DE(Int_t chamberId, Int_t side, Int_t dcsNumber) const
157 /// Convert DCS "slat number" (old convention) to DE (new) convention.
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
163 /// note that dcsNumber should be >=0 and < number of DEs/2 in chamber
165 Int_t nofDE = AliMpDEManager::GetNofDEInChamber(chamberId);
167 Int_t half = nofDE/2;
169 dcsNumber = half - dcsNumber;
171 Int_t quarter = nofDE/4;
172 Int_t threeQuarter = half + quarter;
176 if ( side == 0 ) // left
178 de = threeQuarter + 1 - dcsNumber;
180 else if ( side == 1 ) // right
182 if ( dcsNumber <= quarter )
184 de = dcsNumber + threeQuarter;
188 de = dcsNumber - quarter - 1;
192 return (chamberId+1)*100 + de;
195 //_____________________________________________________________________________
197 AliMpHVNamer::DetElemId2DCS(Int_t detElemId, Int_t& side) const
199 /// Convert DE to DCS "slat number"
202 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
205 AliDebug(1,Form("DetElemId %d invalid",detElemId));
208 Int_t dcsNumber = (detElemId-(chamberId+1)*100);
210 switch ( AliMpDEManager::GetStationType(detElemId) )
212 case AliMp::kStation1:
213 case AliMp::kStation2:
229 case AliMp::kStation345:
231 Int_t nofDE = AliMpDEManager::GetNofDEInChamber(chamberId);
233 Int_t quarter = nofDE/4;
235 Int_t half = nofDE/2;
237 Int_t threeQuarter = half + quarter;
241 if ( dcsNumber <= quarter )
243 dcsNumber += quarter + 1 ;
246 else if ( dcsNumber <= threeQuarter )
248 dcsNumber = ( threeQuarter - dcsNumber + 1 );
251 else if ( dcsNumber > threeQuarter )
253 dcsNumber = dcsNumber - threeQuarter;
260 // dcs convention change : numbering from top, not from bottom
261 dcsNumber = half-dcsNumber;
270 //_____________________________________________________________________________
272 AliMpHVNamer::DCSHVChannelName(Int_t detElemId, Int_t sector) const
274 /// Return the alias name of the HV Channel for a given HV area
276 /// \param sector = 0,1 or 2 for St12, and is unused for st345
278 Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
279 if ( chamberId < 0 ) return 0x0;
282 Int_t dcsNumber = DetElemId2DCS(detElemId,side);
284 switch (AliMpDEManager::GetStationType(detElemId))
286 case AliMp::kStation1:
287 case AliMp::kStation2:
288 return Form(fgHVChannelSt12Pattern[side],chamberId,dcsNumber,sector);
290 case AliMp::kStation345:
291 return Form(fgHVChannelSt345Pattern[side],chamberId,dcsNumber);
299 //_____________________________________________________________________________
301 AliMpHVNamer::DCSHVSwitchName(Int_t detElemId, Int_t pcbNumber) const
303 /// Return the alias name of the HV Switch for a given PCB
304 /// within a slat of St345
306 if (AliMpDEManager::GetStationType(detElemId) == AliMp::kStation345)
308 return Form(fgHVSwitchSt345Pattern,detElemId,pcbNumber);
313 //_____________________________________________________________________________
315 AliMpHVNamer::HVIndexFromDCSAlias(const char* dcsAlias) const
317 /// Converts the dcs alias to a hv index
319 /// dcsAlias has one of the following 3 forms :
321 /// MchHvLv[Left|Right]/Chamber##[Left|Right]/Chamber##[Left|Right]Slat##.actual.vMon
323 /// MchHvLv[Left|Right]/Chamber##[Left|Right]/Chamber##[Left|Right]Quad#Sect#.actual.vMon
325 /// MchDE####dsw#.inValue
327 TString sDcsAlias(dcsAlias);
333 if ( sDcsAlias.Contains("Left") )
337 else if ( sDcsAlias.Contains("Right") )
344 sscanf(sDcsAlias.Data(),fgHVSwitchSt345Pattern,&de,&sw);
352 if ( sDcsAlias.Contains("Quad") )
354 sscanf(sDcsAlias.Data(),fgHVChannelSt12Pattern[side],&n1,&n3,&n4);
361 //_____________________________________________________________________________
363 AliMpHVNamer::DetElemIdFromDCSAlias(const char* dcsAlias) const
365 /// Converts the dcs alias to a detection element identifier
367 /// dcsAlias has one of the following 2 forms :
369 /// MchHvLv[Left|Right]/Chamber##[Left|Right]/Chamber##[Left|Right]Slat##.actual.vMon
371 /// MchHvLv[Left|Right]/Chamber##[Left|Right]/Chamber##[Left|Right]Quad#Sect#.actual.vMon
373 AliDebug(1,Form("dcsAlias=%s",dcsAlias));
375 TString sDcsAlias(dcsAlias);
379 if ( sDcsAlias.Contains("Left") )
383 else if ( sDcsAlias.Contains("Right") )
397 if ( sDcsAlias.Contains("Slat") )
399 sscanf(sDcsAlias.Data(),fgHVChannelSt345Pattern[side],&n1,&n3);
400 detElemId = DCS2DE(n1,side,n3);
401 AliDebug(1,Form("Slat side=%d n1=%d n3=%d de=%d",side,n1,n3,detElemId));
403 else if ( sDcsAlias.Contains("Quad") )
405 sscanf(sDcsAlias.Data(),fgHVChannelSt12Pattern[side],&n1,&n3,&n4);
406 detElemId = 100*(n1+1) + n3;
407 AliDebug(1,Form("Quad side=%d n1=%d n3=%d n4=%d de=%d",side,n1,n3,n4,detElemId));
414 if ( !AliMpDEManager::IsValidDetElemId(detElemId) )
416 AliError(Form("Invalid aliasName %s",dcsAlias));
423 //_____________________________________________________________________________
425 AliMpHVNamer::GenerateAliases() const
427 /// Generate DCS alias names, for MUON Tracker High Voltage system.
429 /// We first generate aliases of HV channels :
431 /// St 1 ch 1 : 12 channels
432 /// ch 2 : 12 channels
433 /// St 2 ch 3 : 12 channels
434 /// ch 4 : 12 channels
435 /// St 3 ch 5 : 18 channels
436 /// ch 6 : 18 channels
437 /// St 4 ch 7 : 26 channels
438 /// ch 8 : 26 channels
439 /// St 5 ch 9 : 26 channels
440 /// ch 10 : 26 channels
442 /// then aliases of HV switches (only for St345) : 1 switch per PCB.
444 /// Returns a TObjArray of TObjString(=alias name)
446 TObjArray* aliases = new TObjArray;
447 aliases->SetOwner(kTRUE);
455 Int_t detElemId = it.CurrentDEId();
456 switch ( AliMpDEManager::GetStationType(detElemId) )
458 case AliMp::kStation1:
459 case AliMp::kStation2:
460 for ( int sector = 0; sector < 3; ++sector)
462 aliases->Add(new TObjString(DCSHVChannelName(detElemId,sector)));
465 case AliMp::kStation345:
466 aliases->Add(new TObjString(DCSHVChannelName(detElemId)));
467 for ( Int_t i = 0; i < NumberOfPCBs(detElemId); ++i )
469 aliases->Add(new TObjString(DCSHVSwitchName(detElemId,i)));
481 //_____________________________________________________________________________
483 AliMpHVNamer::ManuId2Index(Int_t detElemId, Int_t manuId) const
485 /// Convert (de,manu) to hv index, depending on the station
487 AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
488 if ( stationType == AliMp::kStation345 )
490 return ManuId2PCBIndex(detElemId,manuId);
492 else if ( stationType == AliMp::kStation1 || stationType == AliMp::kStation2 )
494 return ManuId2Sector(detElemId,manuId);
499 //_____________________________________________________________________________
501 AliMpHVNamer::ManuId2PCBIndex(Int_t detElemId, Int_t manuId) const
503 /// Returns the index of PCB (within a St345 slat) for a given manu number.
504 /// Returns -1 if (detElemId,manuId) is incorrect
508 const AliMpSlatSegmentation* seg = static_cast<const AliMpSlatSegmentation*>
509 (AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId,manuId));
512 const AliMpSlat* slat = seg->Slat();
514 return slat->FindPCBIndexByMotifPositionID(manuId);
517 //_____________________________________________________________________________
519 AliMpHVNamer::ManuId2Sector(Int_t detElemId, Int_t manuId) const
521 /// Return the HV-sector number (within a St12 quadrant) for a given manu number.
525 const AliMpSectorSegmentation* seg = static_cast<const AliMpSectorSegmentation*>
526 (AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId,manuId));
529 const AliMpSector* sector = seg->GetSector();
530 const AliMpMotifMap* motifMap = sector->GetMotifMap();
531 const AliMpMotifPosition* motifPos = motifMap->FindMotifPosition(manuId);
533 TVector2 lowerLeft(motifPos->Position()-motifPos->Dimensions());
535 Double_t x = lowerLeft.X()*10.0; // cm -> mm
538 AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
540 if ( stationType == AliMp::kStation1 )
542 if ( x < -10 ) AliFatal("");
544 if ( x < 291.65 ) isector = 0;
545 else if ( x < 585.65 ) isector = 1;
546 else if ( x < 879.65 ) isector = 2;
550 if ( x < -140 ) AliFatal("");
552 if ( x < 283.75 ) isector = 0;
553 else if ( x < 603.75 ) isector = 1;
554 else if ( x < 1158.75 ) isector = 2;
560 //_____________________________________________________________________________
562 AliMpHVNamer::NumberOfPCBs(Int_t detElemId) const
564 /// Returns the number of PCB in a given detection element
565 /// Only works for St345
567 AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
568 if ( stationType != AliMp::kStation345 )
574 const AliMpSlatSegmentation* seg = static_cast<const AliMpSlatSegmentation*>
575 (AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath0));
576 const AliMpSlat* slat = seg->Slat();
577 return slat->GetSize();