]>
Commit | Line | Data |
---|---|---|
1ef5468a | 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 | } |