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*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::DetElemIdFromDCSAlias(const char* dcsAlias) const
317 /// Converts the dcs alias to a detection element identifier
319 /// dcsAlias has one of the following 2 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 TString sDcsAlias(dcsAlias);
329 if ( sDcsAlias.Contains("Left") )
333 else if ( sDcsAlias.Contains("Right") )
347 if ( sDcsAlias.Contains("Slat") )
349 sscanf(sDcsAlias.Data(),fgHVChannelSt345Pattern[side],&n1,&n3);
350 detElemId = DCS2DE(n1,side,n3);
352 else if ( sDcsAlias.Contains("Quad") )
354 sscanf(sDcsAlias.Data(),fgHVChannelSt12Pattern[side],&n1,&n3,&n4);
362 if ( !AliMpDEManager::IsValidDetElemId(detElemId) )
364 AliError(Form("Invalid aliasName %s",dcsAlias));
371 //_____________________________________________________________________________
373 AliMpHVNamer::GenerateAliases() const
375 /// Generate DCS alias names, for MUON Tracker High Voltage system.
377 /// We first generate aliases of HV channels :
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
390 /// then aliases of HV switches (only for St345) : 1 switch per PCB.
392 /// Returns a TObjArray of TObjString(=alias name)
394 TObjArray* aliases = new TObjArray;
395 aliases->SetOwner(kTRUE);
403 Int_t detElemId = it.CurrentDEId();
404 switch ( AliMpDEManager::GetStationType(detElemId) )
406 case AliMp::kStation1:
407 case AliMp::kStation2:
408 for ( int sector = 0; sector < 3; ++sector)
410 aliases->Add(new TObjString(DCSHVChannelName(detElemId,sector)));
413 case AliMp::kStation345:
414 aliases->Add(new TObjString(DCSHVChannelName(detElemId)));
415 for ( Int_t i = 0; i < NumberOfPCBs(detElemId); ++i )
417 aliases->Add(new TObjString(DCSHVSwitchName(detElemId,i)));
429 //_____________________________________________________________________________
431 AliMpHVNamer::ManuId2Index(Int_t detElemId, Int_t manuId) const
433 /// Convert (de,manu) to hv index, depending on the station
435 AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
436 if ( stationType == AliMp::kStation345 )
438 return ManuId2PCBIndex(detElemId,manuId);
440 else if ( stationType == AliMp::kStation1 || stationType == AliMp::kStation2 )
442 return ManuId2Sector(detElemId,manuId);
447 //_____________________________________________________________________________
449 AliMpHVNamer::ManuId2PCBIndex(Int_t detElemId, Int_t manuId) const
451 /// Returns the index of PCB (within a St345 slat) for a given manu number.
452 /// Returns -1 if (detElemId,manuId) is incorrect
456 const AliMpSlatSegmentation* seg = static_cast<const AliMpSlatSegmentation*>
457 (AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId,manuId));
458 const AliMpSlat* slat = seg->Slat();
460 return slat->FindPCBIndexByMotifPositionID(manuId);
463 //_____________________________________________________________________________
465 AliMpHVNamer::ManuId2Sector(Int_t detElemId, Int_t manuId) const
467 /// Return the HV-sector number (within a St12 quadrant) for a given manu number.
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);
477 TVector2 lowerLeft(motifPos->Position()-motifPos->Dimensions());
479 Double_t x = lowerLeft.X();
482 AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
484 if ( stationType == AliMp::kStation1 )
486 if ( x < -1 ) AliFatal("");
488 if ( x < 291.65 ) isector = 0;
489 else if ( x < 585.65 ) isector = 1;
490 else if ( x < 879.65 ) isector = 2;
494 if ( x < -14 ) AliFatal("");
496 if ( x < 283.75 ) isector = 0;
497 else if ( x < 603.75 ) isector = 1;
498 else if ( x < 1158.75 ) isector = 2;
504 //_____________________________________________________________________________
506 AliMpHVNamer::NumberOfPCBs(Int_t detElemId) const
508 /// Returns the number of PCB in a given detection element
509 /// Only works for St345
511 AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
512 if ( stationType != AliMp::kStation345 )
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();