Line data Source code
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 "AliMUONTrackerHV.h"
19 :
20 : #include <algorithm>
21 : #include <map>
22 : #include <set>
23 :
24 : #include "AliCDBManager.h"
25 : #include "AliCDBEntry.h"
26 : #include "AliDCSValue.h"
27 : #include "AliGRPObject.h"
28 : #include "AliMpArrayI.h"
29 : #include "AliMpConstants.h"
30 : #include "AliMpDCSNamer.h"
31 : #include "AliMpDEStore.h"
32 : #include "AliMpDetElement.h"
33 : #include "AliMUON2DMap.h"
34 : #include "AliMUONCalibParamND.h"
35 : #include "AliMUONCalibrationData.h"
36 : #include "AliMUONCDB.h"
37 : #include "AliMUONPainterDataRegistry.h"
38 : #include "AliMUONTrackerData.h"
39 : #include "AliMUONTrackerDataWrapper.h"
40 : #include "AliLog.h"
41 :
42 : #include "TCanvas.h"
43 : #include "TGraph.h"
44 : #include "TH2.h"
45 : #include "TLine.h"
46 : #include "TMap.h"
47 : #include "TMultiGraph.h"
48 : #include "TObjArray.h"
49 : #include "TObjString.h"
50 : #include "TStyle.h"
51 : #include "Riostream.h"
52 :
53 : //
54 : // Class to inspect the MUON TRACKER HV values
55 : //
56 : // With this class you can :
57 : //
58 : // a) get a list of trips (method ReportTrips)
59 : // b) print the values for some (or all) HV channels (method Print)
60 : // c) plot the values for some (or all) HV channels (method Plot)
61 : // d) get a list of HV channels that are "OFF" (methods Scan and HVoff)
62 : //
63 : // Note that in this class, all the output (either text or canvas) or the
64 : // channel *names* used are the same as in the DCS UI at Pt2
65 : // Specifically the chamber ids start at 1, the slat numbers at 1 and
66 : // the quad and sect number at 1 also. And not at zero like for the
67 : // DCS *aliases*. On the contraty, the internal map, coming from the OCDB,
68 : // only contains aliases, not names. Confusing ? It is.
69 : //
70 :
71 : ///\cond CLASSIMP
72 12 : ClassImp(AliMUONTrackerHV)
73 : ///\endcond
74 :
75 : //______________________________________________________________________________
76 : AliMUONTrackerHV::AliMUONTrackerHV(const char* runlist, const char* ocdbPath)
77 0 : : AliMUONTrackerVoltages(runlist,ocdbPath)
78 0 : {
79 : // ctor from a runlist (txt file)
80 0 : fOCDBObjectPath = "MUON/Calib/HV";
81 0 : }
82 :
83 : //______________________________________________________________________________
84 : AliMUONTrackerHV::AliMUONTrackerHV(Int_t runNumber, const char* ocdbPath)
85 0 : : AliMUONTrackerVoltages(runNumber,ocdbPath)
86 0 : {
87 : // ctor for a single run
88 0 : fOCDBObjectPath = "MUON/Calib/HV";
89 0 : }
90 :
91 : //______________________________________________________________________________
92 : AliMUONTrackerHV::~AliMUONTrackerHV()
93 0 : {
94 : // dtor
95 0 : }
96 :
97 : //______________________________________________________________________________
98 : TMap*
99 : AliMUONTrackerHV::CreateMap(Int_t runNumber, Bool_t patched) const
100 : {
101 0 : if (!patched) {
102 0 : return AliMUONTrackerVoltages::CreateMap(runNumber,kFALSE);
103 : }
104 :
105 0 : return AliMUONCalibrationData::CreateHV(runNumber,0x0,kTRUE,0x0,kTRUE);
106 0 : }
107 :
108 : //______________________________________________________________________________
109 : void
110 : AliMUONTrackerHV::Scan(Int_t verbose)
111 : {
112 : /// Retrieve HV values from OCDB for a given run list, and check whether
113 : /// we have some issues with them...
114 : /// If you pipe the results of this into a text file, you can then
115 : /// feed it to the HVoff method for further investigations.
116 : ///
117 :
118 0 : if ( fRunList.empty() )
119 : {
120 0 : AliError("No runs to process...");
121 0 : return;
122 : }
123 :
124 0 : AliCDBManager::Instance()->SetDefaultStorage(fOCDBPath.Data());
125 :
126 0 : for ( std::vector<int>::size_type i = 0; i < fRunList.size(); ++i )
127 : {
128 0 : AliMUONCDB::CheckHV(fRunList[i],verbose);
129 : }
130 0 : }
131 :
132 : //______________________________________________________________________________
133 : void AliMUONTrackerHV::HVoff(const char* logfile, const char* outputBaseName)
134 : {
135 : /// Check the number of HV which have problem
136 : /// the input is the output of e.g.
137 : /// .L MUONTrackerHV.C+
138 : /// ScanHV("lhc11de.list");> lhc11de.log
139 : ///
140 :
141 0 : gStyle->SetOptStat(0);
142 :
143 0 : char line[1024];
144 :
145 0 : std::ifstream in(logfile);
146 0 : int run(-1),a,b,c,d,e,f,g,h,z,other;
147 0 : std::map<int,std::string> results;
148 :
149 0 : std::string message;
150 : const char* testProblem = "I-AliMUONCDB::CheckHV::CheckHV: Problem at ";
151 :
152 0 : while ( in.getline(line,1023,'\n') )
153 : {
154 0 : TString sline(line);
155 0 : if (sline.Contains("SUMMARY"))
156 : {
157 0 : AliInfo(line);
158 0 : int r;
159 0 : sscanf(line,"I-AliMUONCDB::CheckHV::CheckHV: RUN %09d HVchannel SUMMARY : # of cases A(%3d) B(%3d) C(%3d) D(%3d) E(%3d) F(%3d) G(%3d) H(%3d) Z(%3d) OTHER(%3d)",
160 : &r,&a,&b,&c,&d,&e,&f,&g,&h,&z,&other);
161 0 : if ( r != run )
162 : {
163 0 : if ( run == -1 )
164 : {
165 0 : AliCDBManager::Instance()->SetDefaultStorage(fOCDBPath.Data());
166 0 : AliCDBManager::Instance()->SetRun(r);
167 0 : AliMUONCDB::LoadMapping();
168 : }
169 :
170 0 : if ( run > 0 )
171 : {
172 0 : results.insert(std::make_pair(run,message));
173 :
174 0 : }
175 0 : message = "";
176 0 : run = r;
177 0 : }
178 0 : }
179 0 : else if ( sline.Contains(testProblem) )
180 : {
181 0 : message += "|";
182 0 : message += sline(strlen(testProblem),sline.Length()-1).Data();
183 : }
184 0 : }
185 :
186 0 : results.insert(std::make_pair(run,message));
187 :
188 0 : TH2* hvoff = new TH2I(outputBaseName,outputBaseName,1,0,1,1,0,1);
189 :
190 0 : std::map<int,std::string>::const_iterator it;
191 :
192 0 : for ( it = results.begin(); it != results.end(); ++it )
193 : {
194 0 : AliInfo(Form("%d -> %s",it->first,it->second.c_str()));
195 0 : TObjArray* split = TString(it->second.c_str()).Tokenize("|");
196 0 : TIter next(split);
197 : TObjString* str;
198 0 : while ( ( str = static_cast<TObjString*>(next()) ) )
199 : {
200 0 : TString s(str->String());
201 0 : TObjArray* parts = s.Tokenize(":");
202 0 : TString alias = (static_cast<TObjString*>(parts->At(0)))->String();
203 0 : TString channel = DCSNamer()->DCSNameFromAlias(alias.Data());
204 0 : channel += Form("(%4d)",DCSNamer()->DetElemIdFromDCSAlias(alias.Data()));
205 0 : channel.ReplaceAll(".actual.vMon","");
206 0 : hvoff->Fill(Form("%6d",it->first),channel.Data(),1.0);
207 0 : delete parts;
208 0 : }
209 0 : delete split;
210 0 : }
211 :
212 0 : hvoff->LabelsDeflate("x");
213 0 : hvoff->LabelsDeflate("y");
214 0 : hvoff->LabelsOption("x","<");
215 0 : hvoff->LabelsOption("y","<");
216 :
217 0 : TCanvas* c1 = new TCanvas;
218 0 : c1->SetLeftMargin(0.35);
219 0 : hvoff->Draw("text");
220 0 : c1->Print(Form("%s.pdf",outputBaseName));
221 0 : TCanvas* c2 = new TCanvas;
222 0 : TH1* hx = hvoff->ProjectionX("hvoffperrun");
223 0 : hx->Draw();
224 0 : c2->Print(Form("%s-perrun.pdf",outputBaseName));
225 0 : TCanvas* c3 = new TCanvas;
226 0 : c3->SetBottomMargin(0.55);
227 0 : TH1* perchannel = hvoff->ProjectionY("hvoffperchannel");
228 0 : perchannel->GetXaxis()->SetBit(TAxis::kLabelsVert);
229 0 : perchannel->GetXaxis()->LabelsOption(">");
230 0 : perchannel->Draw("texthist");
231 0 : c3->Print(Form("%s-perchannel.pdf",outputBaseName));
232 0 : }
233 :
234 : //______________________________________________________________________________
235 : void
236 : AliMUONTrackerHV::Plot(const char* dcsname, Bool_t withPatch, Bool_t plotIntermediate)
237 : {
238 : /// Show HV values for a given dcs name (or all if dcsname=0)
239 : /// Each canvas for each run will go to a separate PDF file
240 :
241 0 : AliCDBManager::Instance()->SetDefaultStorage(fOCDBPath.Data());
242 0 : TList messages;
243 0 : messages.SetOwner(kTRUE);
244 0 : TObjArray graphs;
245 :
246 0 : for ( std::vector<int>::size_type i = 0; i < fRunList.size(); ++i )
247 : {
248 0 : Int_t runNumber = fRunList[i];
249 :
250 0 : messages.Delete();
251 :
252 0 : AliCDBManager::Instance()->SetRun(runNumber);
253 :
254 0 : TMap* m = AliMUONCalibrationData::CreateHV(runNumber,0x0,withPatch,&messages,kTRUE);
255 :
256 0 : TMultiGraph* mg = Map2Graph(m,dcsname);
257 :
258 0 : if ( !mg ) continue;
259 :
260 0 : graphs.Add(mg);
261 :
262 0 : TString cname(Form("MCH_HV_RUN%09d",runNumber));
263 :
264 0 : if ( strlen(dcsname) > 0 )
265 : {
266 0 : TString s(dcsname);
267 0 : s.ReplaceAll("/","_");
268 0 : cname += Form("_dcsname_%s",s.Data());
269 0 : }
270 :
271 0 : AliCDBEntry* e = AliCDBManager::Instance()->Get("GRP/GRP/Data",runNumber);
272 :
273 : TLine* startRunLine(0);
274 : TLine* endRunLine(0);
275 : time_t start(0);
276 : time_t end(0);
277 :
278 0 : if ( e )
279 : {
280 0 : AliGRPObject* grp = static_cast<AliGRPObject*>(e->GetObject());
281 0 : if (grp)
282 : {
283 0 : start = grp->GetTimeStart();
284 0 : end = grp->GetTimeEnd();
285 0 : }
286 0 : }
287 :
288 0 : if ( end )
289 : {
290 0 : TGraph* g = new TGraph(1);
291 0 : g->SetPoint(0,end,0);
292 0 : mg->Add(g,"");
293 0 : }
294 :
295 0 : if ( plotIntermediate )
296 : {
297 0 : TCanvas* c = new TCanvas(cname.Data(),cname.Data());
298 :
299 0 : c->Draw();
300 :
301 0 : mg->SetTitle(cname.Data());
302 :
303 0 : mg->Draw("AL");
304 :
305 0 : TimeAxis(mg);
306 :
307 0 : if ( start )
308 : {
309 0 : startRunLine = new TLine(start,mg->GetYaxis()->GetXmin(),start,mg->GetYaxis()->GetXmax());
310 0 : startRunLine->SetLineColor(2);
311 0 : startRunLine->SetLineWidth(4);
312 : }
313 0 : if ( end )
314 : {
315 0 : endRunLine = new TLine(end,mg->GetYaxis()->GetXmin(),end,mg->GetYaxis()->GetXmax());
316 0 : endRunLine->SetLineColor(2);
317 0 : endRunLine->SetLineWidth(4);
318 : }
319 :
320 0 : if ( startRunLine ) startRunLine->Draw();
321 0 : if ( endRunLine ) endRunLine->Draw();
322 :
323 0 : c->SaveAs(Form("%s.pdf",cname.Data()));
324 0 : }
325 0 : }
326 :
327 0 : new TCanvas;
328 :
329 0 : TMultiGraph* g = CombineMulti(graphs);
330 :
331 0 : TIter next(g->GetListOfGraphs());
332 : TGraph* gi;
333 :
334 0 : while ( ( gi = static_cast<TGraph*>(next())))
335 : {
336 0 : gi->SetMarkerStyle(kPlus);
337 : }
338 0 : g->Draw("alp");
339 0 : TimeAxis(g);
340 0 : }
341 :
342 : //______________________________________________________________________________
343 : void
344 : AliMUONTrackerHV::ReportTrips(Bool_t includeLowOnes)
345 : {
346 : /// Report trips
347 : /// if includeLowOnes is kTRUE we'll report also the trips which starts from non-operational voltage values
348 :
349 0 : AliCDBManager::Instance()->SetDefaultStorage(fOCDBPath.Data());
350 :
351 0 : TList messages;
352 0 : messages.SetOwner(kTRUE);
353 : TObjString* msg(0);
354 :
355 0 : std::map<std::string,int> channels;
356 :
357 0 : for ( std::vector<int>::size_type i = 0; i < fRunList.size(); ++i )
358 : {
359 0 : Int_t runNumber = fRunList[i];
360 :
361 0 : AliInfo("---------------------");
362 :
363 : Int_t ntrips(0);
364 :
365 0 : messages.Delete();
366 :
367 0 : AliCDBManager::Instance()->SetRun(runNumber);
368 :
369 0 : AliMUONCalibrationData::CreateHV(runNumber,0x0,kTRUE,&messages,kTRUE);
370 :
371 0 : if (!AliMpDEStore::Instance(false))
372 : {
373 0 : AliMUONCDB::LoadMapping();
374 : }
375 :
376 0 : TIter next(&messages);
377 :
378 0 : while ( ( msg = static_cast<TObjString*>(next())) )
379 : {
380 0 : if ( msg->String().Contains("TRIP") && ( includeLowOnes || !msg->String().Contains("LOWTRIP") ) )
381 : {
382 0 : ++ntrips;
383 0 : }
384 : }
385 :
386 0 : AliInfo(Form("RUN %09d - %d trip%c",runNumber,ntrips,(ntrips>1 ? 's':' ')));
387 :
388 0 : next.Reset();
389 0 : std::map<int,std::string> report;
390 :
391 0 : while ( ( msg = static_cast<TObjString*>(next())) )
392 : {
393 0 : if ( msg->String().Contains("TRIP") )
394 : {
395 0 : TObjArray* parts = msg->String().Tokenize(" ");
396 0 : TString channelName(static_cast<TObjString*>(parts->At(0))->String());
397 :
398 0 : for ( Int_t ip = 0; ip <= parts->GetLast(); ++ip)
399 : {
400 0 : TString p(static_cast<TObjString*>(parts->At(ip))->String());
401 :
402 0 : if ( p.Contains("TRIP") )
403 : {
404 0 : if ( includeLowOnes || !p.Contains("LOWTRIP") )
405 : {
406 0 : TString ts(static_cast<TObjString*>(parts->At(ip+2))->String());
407 :
408 0 : ip += 3;
409 :
410 0 : Int_t index = ts.Index("TS:");
411 :
412 0 : UInt_t timeStamp = TString(ts(index+strlen("TS:"),ts.Length()-index)).Atoi();
413 :
414 0 : TString tmp(msg->String());
415 0 : tmp.ReplaceAll(channelName.Data(),DCSNamer()->DCSNameFromAlias(channelName.Data()));
416 0 : report[timeStamp] = tmp.Data();
417 0 : channels[channelName.Data()]++;
418 0 : }
419 : }
420 0 : }
421 0 : delete parts;
422 0 : }
423 : }
424 :
425 0 : for ( std::map<int,std::string>::const_iterator it = report.begin(); it != report.end(); ++it )
426 : {
427 0 : AliInfo(Form("%s %s",TTimeStamp(it->first).AsString("s"),it->second.c_str()));
428 : }
429 0 : }
430 :
431 0 : AliInfo("--------------------------------------------------------------------");
432 0 : AliInfo("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
433 :
434 : int totalTrips(0);
435 0 : AliMUON2DMap tripMap(kTRUE);
436 0 : Int_t nofChannels(AliMpConstants::ManuNofChannels());
437 :
438 0 : for ( std::map<std::string,int>::const_iterator it = channels.begin(); it != channels.end(); ++it )
439 : {
440 0 : AliInfo(Form("%40s %3d",DCSNamer()->DCSNameFromAlias(it->first.c_str()).Data(),it->second));
441 0 : totalTrips += it->second;
442 :
443 0 : Int_t detElemId = DCSNamer()->DetElemIdFromDCSAlias(it->first.c_str());
444 :
445 0 : AliMpDetElement* de = AliMpDEStore::Instance()->GetDetElement(detElemId);
446 :
447 : // build the list of manuIds for this channel
448 0 : AliMpArrayI manuArray;
449 :
450 0 : manuArray.SetSize(300);
451 :
452 0 : Int_t index = DCSNamer()->DCSIndexFromDCSAlias(it->first.c_str());
453 : Int_t firstIndex(index);
454 : Int_t lastIndex(index);
455 :
456 0 : if ( index < 0 )
457 : {
458 : // it's a slat, must loop over PCBs
459 : firstIndex = 0;
460 0 : lastIndex = DCSNamer()->NumberOfPCBs(detElemId)-1;
461 0 : }
462 :
463 0 : for ( int i = firstIndex; i <= lastIndex ; ++i )
464 : {
465 0 : const AliMpArrayI* ma = de->ManusForHV(i);
466 0 : if (!ma)
467 : {
468 0 : AliError(Form("Could not get ma for de %d index %d",detElemId,i));
469 0 : continue;
470 : }
471 0 : for ( int j = 0; j < ma->GetSize(); ++j )
472 : {
473 0 : manuArray.Add(ma->GetValue(j),kFALSE);
474 : }
475 0 : }
476 :
477 0 : for ( Int_t iManu = 0; iManu < manuArray.GetSize(); ++iManu )
478 : {
479 0 : Int_t manuId = manuArray.GetValue(iManu);
480 :
481 0 : AliMUONVCalibParam* tripRate = new AliMUONCalibParamND(1,nofChannels,detElemId,manuId,0);
482 :
483 0 : tripMap.Add(tripRate);
484 :
485 0 : for ( Int_t j = 0 ; j < nofChannels; ++j )
486 : {
487 0 : tripRate->SetValueAsDouble(j,0,it->second*1.0);
488 : }
489 : }
490 0 : }
491 :
492 0 : AliInfo("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
493 0 : AliInfo(Form("Total of %3d trips for %4ld runs",totalTrips,fRunList.size()));
494 :
495 0 : AliMUONTrackerData* data = new AliMUONTrackerData("tripcount","Number of trips",1);
496 0 : data->Add(tripMap);
497 0 : data->SetDimensionName(0,"ntrips");
498 :
499 0 : AliMUONVTrackerDataMaker* dw = new AliMUONTrackerDataWrapper(data);
500 :
501 0 : AliMUONPainterDataRegistry::Instance()->Register(dw);
502 :
503 0 : }
504 :
505 : //______________________________________________________________________________
506 : Int_t AliMUONTrackerHV::CompareMaps(const TMap& hv1, const TMap& hv2, Bool_t verbose) const
507 : {
508 : /// Compare two HV maps (only HV voltages for the moment)
509 : /// Return the number of HV channels for which there is a difference
510 :
511 : Int_t ndiff(0);
512 0 : TIter next(&hv1);
513 : TObjString* hvChannelName;
514 :
515 0 : while ( ( hvChannelName = static_cast<TObjString*>(next()) ) )
516 : {
517 0 : TString name(hvChannelName->String());
518 :
519 0 : if ( name.Contains("sw") ) continue; // skip switches for the moment
520 0 : if ( name.Contains("iMon") ) continue; // skip HV currents for the moment
521 :
522 : Bool_t st1Check(kFALSE);
523 :
524 0 : if ( name.Contains("Chamber00Left") )
525 : {
526 0 : if (name.Contains("Quad1Sect0")) st1Check=kTRUE;
527 0 : if (name.Contains("Quad1Sect1")) st1Check=kTRUE;
528 0 : if (name.Contains("Quad1Sect2")) st1Check=kTRUE;
529 0 : if (name.Contains("Quad2Sect2")) st1Check=kTRUE;
530 0 : if (name.Contains("Quad2Sect1")) st1Check=kTRUE;
531 0 : if (name.Contains("Quad2Sect0")) st1Check=kTRUE;
532 : }
533 0 : else if ( name.Contains("Chamber01Left"))
534 : {
535 0 : if (name.Contains("Quad2Sect2")) st1Check=kTRUE;
536 0 : if (name.Contains("Quad2Sect0")) st1Check=kTRUE;
537 : }
538 :
539 0 : TPair* hvPair1 = static_cast<TPair*>(hv1.FindObject(name.Data()));
540 0 : TObjArray* values1 = static_cast<TObjArray*>(hvPair1->Value());
541 :
542 0 : TPair* hvPair2 = static_cast<TPair*>(hv2.FindObject(name.Data()));
543 0 : TObjArray* values2 = static_cast<TObjArray*>(hvPair2->Value());
544 :
545 : Bool_t same(kTRUE);
546 :
547 0 : if ( values1->GetEntries() != values2->GetEntries() )
548 : {
549 : same = kFALSE;
550 0 : }
551 : else
552 : {
553 0 : Int_t n = values1->GetEntries();
554 0 : for ( Int_t i = 0; i < n && same == kTRUE; ++i )
555 : {
556 0 : AliDCSValue* v1 = dynamic_cast<AliDCSValue*>(values1->At(i));
557 0 : AliDCSValue* v2 = dynamic_cast<AliDCSValue*>(values2->At(i));
558 :
559 0 : if ( v1->Compare(v2) != 0 || v1->GetType() != v2->GetType() || !IsAlmostEqualRelative(v1->GetFloat(),v2->GetFloat() ))
560 : {
561 : same = kFALSE;
562 0 : }
563 : }
564 : }
565 :
566 0 : if (!same)
567 : {
568 0 : ++ndiff;
569 0 : }
570 :
571 0 : if ( verbose && !same && st1Check )
572 : {
573 0 : std::cout << name << std::endl;
574 0 : values1->Print();
575 0 : values2->Print();
576 : }
577 0 : }
578 :
579 : return ndiff;
580 0 : }
|