]>
Commit | Line | Data |
---|---|---|
61f6b45e | 1 | //////////////////////////////////////////////////////////////////////////// |
2 | // // | |
3 | // Trend Value Manager // | |
4 | // // | |
5 | // Mediates interaction with DB (OCDB ?!) // // // | |
6 | // Authors: // | |
7 | // Alexandru Bercuci <A.Bercuci@gsi.de> // | |
8 | // // | |
9 | //////////////////////////////////////////////////////////////////////////// | |
10 | ||
847569f2 | 11 | #include "TFile.h" |
12 | #include "TKey.h" | |
3240bb4a | 13 | #include "TObjArray.h" |
847569f2 | 14 | #include "TH1F.h" |
15 | #include "TAxis.h" | |
aebcb1ff | 16 | #include "TGraphErrors.h" |
dffc3357 | 17 | #include "TLine.h" |
847569f2 | 18 | #include "TCanvas.h" |
19 | #include "TString.h" | |
20 | ||
3240bb4a | 21 | #include "AliLog.h" |
3240bb4a | 22 | #include "AliTRDtrendingManager.h" |
23 | ||
24 | ClassImp(AliTRDtrendingManager) | |
25 | ||
26 | AliTRDtrendingManager* AliTRDtrendingManager::fgInstance=NULL; | |
95d47440 | 27 | //Bool_t AliTRDtrendingManager::fgTerminated = kFALSE; |
3240bb4a | 28 | |
29 | //____________________________________________ | |
30 | AliTRDtrendingManager* AliTRDtrendingManager::Instance() | |
31 | { | |
32 | // | |
33 | // Singleton implementation | |
34 | // Returns an instance of this class, it is created if neccessary | |
35 | // | |
95d47440 | 36 | // if (fgTerminated) return NULL; |
847569f2 | 37 | if (!fgInstance) fgInstance = new AliTRDtrendingManager(); |
3240bb4a | 38 | return fgInstance; |
39 | } | |
40 | ||
41 | //____________________________________________ | |
42 | void AliTRDtrendingManager::Terminate() | |
43 | { | |
44 | // | |
45 | // Singleton implementation | |
46 | // Deletes the instance of this class and sets the terminated flag, | |
47 | // instances cannot be requested anymore | |
48 | // This function can be called several times. | |
49 | // | |
50 | ||
95d47440 | 51 | /* fgTerminated = kTRUE;*/ |
3240bb4a | 52 | if (fgInstance != NULL) { |
847569f2 | 53 | if(TFile::Open("TRD.Trend.root", "RECREATE")){ |
cc98ff07 | 54 | if(fEntries) fEntries->Write(); |
847569f2 | 55 | gFile->Close(); |
56 | } | |
57 | delete fgInstance; fgInstance = NULL; | |
3240bb4a | 58 | } |
59 | } | |
60 | ||
61 | //____________________________________________ | |
62 | AliTRDtrendingManager::AliTRDtrendingManager() | |
63 | : TObject() | |
64 | ,fEntries(NULL) | |
3240bb4a | 65 | { |
61f6b45e | 66 | // Constructor |
3240bb4a | 67 | } |
68 | ||
69 | //____________________________________________ | |
70 | AliTRDtrendingManager::~AliTRDtrendingManager() | |
71 | { | |
61f6b45e | 72 | // Destructor |
95d47440 | 73 | if(fEntries){ |
74 | fEntries->Delete(); | |
75 | delete fEntries; | |
76 | } | |
3240bb4a | 77 | } |
78 | ||
79 | //____________________________________________ | |
80 | void AliTRDtrendingManager::AddValue( | |
847569f2 | 81 | const Char_t *name |
82 | ,Double_t mean,Double_t sigm | |
83 | ,const Char_t *title | |
61f6b45e | 84 | ,const Char_t *responsible |
85 | ,const Char_t *notifiables | |
847569f2 | 86 | ,Char_t **messages |
3240bb4a | 87 | ) |
88 | { | |
89 | // Expert Function !!! | |
90 | // Add a trend value to the map already loaded | |
91 | // If no map loaded create a new one from scratch | |
92 | // | |
93 | // class_name : name of the performance task | |
94 | // name : name of the value to be trended | |
95 | // title : description of the value to be trended | |
3240bb4a | 96 | // messages : array of alarm messages for each alarm level |
97 | // responsible: name and email of the responsible person. Format "name/email" | |
98 | // notifiables: name and email of the notifiable persons. Format "name1/email1, name2/email2, etc" | |
99 | // | |
3240bb4a | 100 | |
847569f2 | 101 | if(!fEntries){ // if no trending map defined create one |
102 | AliDebug(1, "No trending map loaded. Create one from scratch."); | |
95d47440 | 103 | MakeList(1000); |
3240bb4a | 104 | } |
847569f2 | 105 | |
95d47440 | 106 | if(GetValue(name)){ |
107 | AliInfo(Form("Trend value \"%s\" already in list. Use Modify function", name)); | |
108 | return; | |
109 | } | |
110 | // create new trending value` | |
111 | AliTRDtrendValue *fValue = new AliTRDtrendValue(name, title?title:""); | |
112 | fValue->Set(mean, sigm); | |
113 | if(messages) for(Int_t ilevel(AliTRDtrendValue::kNlevels); ilevel--;) if(messages[ilevel]) fValue->SetAlarm(ilevel, messages[ilevel]); | |
114 | TObjArray *r(NULL); | |
115 | if(responsible){ | |
116 | TString s(responsible); | |
117 | r=s.Tokenize("/"); | |
118 | if(r->GetEntriesFast()!=2){ | |
119 | AliWarning("Responsible name/email incorrectly formated."); | |
120 | } else { | |
121 | fValue->SetResponsible(((TObjString*)r->At(0))->String().Data(), ((TObjString*)r->At(1))->String().Data()); | |
122 | } | |
123 | r->Delete(); delete r; | |
124 | } | |
125 | if(notifiables){ | |
126 | TString s(notifiables); | |
127 | TObjArray *n=s.Tokenize(","); | |
128 | for(Int_t in(0); in<TMath::Min(AliTRDtrendValue::kNnotifiable, n->GetEntriesFast()); in++){ | |
129 | TString ss(((TObjString*)n->At(in))->String()); | |
130 | r=ss.Tokenize("/"); | |
847569f2 | 131 | if(r->GetEntriesFast()!=2){ |
95d47440 | 132 | AliWarning(Form("Notifiable person name/email incorrectly formated for [%s].", ss.Data())); |
847569f2 | 133 | } else { |
95d47440 | 134 | fValue->SetNotifiable(((TObjString*)r->At(0))->String().Data(), ((TObjString*)r->At(1))->String().Data()); |
847569f2 | 135 | } |
dffc3357 | 136 | r->Delete(); delete r; |
847569f2 | 137 | } |
95d47440 | 138 | n->Delete(); delete n; |
3240bb4a | 139 | } |
95d47440 | 140 | fEntries->AddLast(fValue); |
3240bb4a | 141 | } |
142 | ||
143 | //____________________________________________ | |
847569f2 | 144 | AliTRDtrendValue* AliTRDtrendingManager::GetValue(const Char_t *name) |
3240bb4a | 145 | { |
847569f2 | 146 | // Search trend value list by value "name" formatted according to "class_name" |
3240bb4a | 147 | if(!fEntries){ |
148 | AliError("No trending map defined."); | |
149 | return NULL; | |
150 | } | |
95d47440 | 151 | return (AliTRDtrendValue*)fEntries->FindObject(name); |
847569f2 | 152 | } |
153 | ||
154 | //____________________________________________ | |
dffc3357 | 155 | TH1* AliTRDtrendingManager::MakeTrends(const char *fileList, TObjArray *dump) |
847569f2 | 156 | { |
157 | // Make trends with reference to DB for all trend files in "fileList". | |
158 | // The DB should be loaded | |
159 | if(!fEntries){ | |
160 | AliWarning("Trending map undefined"); | |
dffc3357 | 161 | return NULL; |
847569f2 | 162 | } |
163 | Int_t ntv(fEntries->GetEntries()); | |
164 | ||
165 | FILE *fp(NULL); | |
166 | if(!(fp= fopen(fileList, "rt"))){ | |
167 | AliWarning(Form("Can not open file list \"%s\"", fileList)); | |
dffc3357 | 168 | return NULL; |
3240bb4a | 169 | } |
dffc3357 | 170 | Int_t *na = new Int_t[ntv]; memset(na, 0, ntv*sizeof(Int_t)); |
171 | Float_t *la = new Float_t[ntv]; memset(la, 0, ntv*sizeof(Float_t)); | |
df72fea3 | 172 | Float_t *lm = new Float_t[ntv]; for(Int_t im(0); im<ntv; im++) lm[im] = 1.e5; |
173 | Float_t *lM = new Float_t[ntv]; for(Int_t im(0); im<ntv; im++) lM[im] = -1.e5; | |
aebcb1ff | 174 | TGraphErrors **g = new TGraphErrors*[ntv]; memset(g, 0, ntv*sizeof(TGraphErrors*)); |
847569f2 | 175 | AliTRDtrendValue *TV(NULL), *tv(NULL); |
176 | TString sfp; Int_t run[10000], nr(0); | |
177 | while(sfp.Gets(fp)){ | |
178 | // guess run no from path. Do we need a more robust approach ? | |
179 | TObjArray *afp=sfp.Tokenize("/"); | |
180 | Int_t idx = afp->GetEntries()-2; | |
181 | Int_t rno = ((TObjString*)(*afp)[idx])->GetString().Atoi(); | |
dffc3357 | 182 | afp->Delete(); delete afp; |
847569f2 | 183 | if(!TFile::Open(sfp.Data())) continue; |
dffc3357 | 184 | |
0f2c4c4f | 185 | run[nr] = rno; Int_t nmiss(0); |
847569f2 | 186 | for(Int_t it(0); it<ntv; it++){ |
187 | if(!(TV = (AliTRDtrendValue*)fEntries->At(it))) continue; | |
188 | if(!(tv = (AliTRDtrendValue*)gFile->Get(TV->GetName()))) { | |
0f2c4c4f | 189 | AliDebug(1, Form("Missing %09d.%s", rno, TV->GetName())); |
190 | nmiss++; | |
847569f2 | 191 | continue; |
192 | } | |
95d47440 | 193 | if(tv->GetVal()<=-998. || |
0f2c4c4f | 194 | (strstr(TV->GetName(), "TRDcheckDET")&&TMath::Abs(tv->GetVal())<1.e-5) || |
5047978d | 195 | (strstr(TV->GetName(), "TRDefficiency")&&tv->GetVal()<1.e-5) || |
0f2c4c4f | 196 | (!(strcmp(TV->GetName(), "TRDcheckDET_ChargeTracklet"))&&TMath::Abs(tv->GetVal())<1.e1)) continue; |
dffc3357 | 197 | if(IsRelativeMeanSigma()){ |
198 | (*tv)/=(*TV); | |
199 | la[it]+=tv->GetVal(); na[it]++; | |
200 | } else { | |
201 | if(tv->GetVal()<lm[it]) lm[it]=tv->GetVal(); | |
202 | if(tv->GetVal()>lM[it])lM[it]=tv->GetVal(); | |
203 | } | |
847569f2 | 204 | if(!g[it]){ |
aebcb1ff | 205 | g[it] = new TGraphErrors(); |
847569f2 | 206 | g[it]->SetNameTitle(TV->GetName(), TV->GetTitle()); |
dffc3357 | 207 | g[it]->SetMarkerStyle(4);g[it]->SetMarkerSize(1.2); |
208 | g[it]->SetLineStyle(2);g[it]->SetLineWidth(1); | |
847569f2 | 209 | } |
aebcb1ff | 210 | Int_t ip(g[it]->GetN()); |
211 | g[it]->SetPoint(ip, nr, tv->GetVal()); | |
212 | g[it]->SetPointError(ip, 0., tv->GetErr()); | |
847569f2 | 213 | } |
0f2c4c4f | 214 | if(Float_t(nmiss)/ntv>.1) AliWarning(Form("Run[%09d] Missing %6.2f%% values", rno, 1.e2*nmiss/ntv)); |
847569f2 | 215 | nr++; |
216 | } | |
217 | ||
218 | // Draw | |
219 | TH1 *hT = new TH1F("hT", ";#bf{RUN};", nr, -0.5, nr-0.5); | |
220 | TAxis *ax = hT->GetXaxis(); ax->SetTitleOffset(2.6);ax->CenterTitle(); ax->SetBit(TAxis::kLabelsVert); | |
668a0654 | 221 | TAxis *ay = hT->GetYaxis(); ay->SetTitleOffset(IsRelativeMeanSigma()?0.4:0.75);ay->CenterTitle(); ay->SetAxisColor(kRed); ay->SetDecimals(); |
847569f2 | 222 | for(Int_t ir(0); ir<nr; ir++) ax->SetBinLabel(ir+1, Form("%09d", run[ir])); |
223 | ||
dffc3357 | 224 | TLine *line(NULL); |
225 | TCanvas *c = new TCanvas("c", "TRD Trend", 1, 1, 2400, 1000); | |
668a0654 | 226 | c->SetLeftMargin(IsRelativeMeanSigma()?0.03666361:0.05685619); |
847569f2 | 227 | c->SetRightMargin(0.005499542); |
228 | c->SetTopMargin(0.02542373); | |
229 | c->SetBottomMargin(0.1758475); | |
230 | for(Int_t it(0); it<ntv; it++){ | |
668a0654 | 231 | if(!g[it]) continue; |
847569f2 | 232 | c->Clear(); |
668a0654 | 233 | if(IsRelativeMeanSigma()){ |
234 | ay->SetRangeUser(-5, 5); | |
235 | ay->SetTitle(Form("#bf{%s [#sigmau]}", g[it]->GetTitle())); | |
dffc3357 | 236 | line = new TLine(-0.5, na[it]?(la[it]/na[it]):0., nr-0.5, na[it]?(la[it]/na[it]):0.); |
237 | line->SetLineColor(kBlue); | |
668a0654 | 238 | } else { |
df72fea3 | 239 | ay->SetRangeUser(lm[it]-0.1*(lM[it]-lm[it]), lM[it]+0.1*(lM[it]-lm[it])); |
668a0654 | 240 | ay->SetTitle(Form("#bf{%s}", g[it]->GetTitle())); |
241 | } | |
242 | hT->Draw("p"); | |
aebcb1ff | 243 | g[it]->Draw("ple5"); |
dffc3357 | 244 | if(line) line->Draw(); |
847569f2 | 245 | c->Modified(); c->Update(); c->SaveAs(Form("Trend_%s.gif", g[it]->GetName())); |
dffc3357 | 246 | if(dump) dump->Add(g[it]); |
247 | else delete g[it]; | |
248 | if(line) delete line; | |
847569f2 | 249 | } |
250 | delete [] g; | |
df72fea3 | 251 | delete [] lm; |
252 | delete [] lM; | |
dffc3357 | 253 | delete [] la; |
254 | delete [] na; | |
255 | return hT; | |
3240bb4a | 256 | } |
257 | ||
258 | //____________________________________________ | |
259 | Bool_t AliTRDtrendingManager::ModifyValue( | |
847569f2 | 260 | const Char_t *name |
261 | ,const Char_t *title | |
262 | ,Double_t mean, Double_t sgm | |
3240bb4a | 263 | ,Char_t **messages |
61f6b45e | 264 | ,const Char_t *responsible |
265 | ,const Char_t *notifiables | |
3240bb4a | 266 | ) |
267 | { | |
268 | // Expert Function !!! | |
269 | // Modify a trend value in the map already loaded | |
270 | // see function AddValue() for explanation of input format. | |
271 | ||
272 | if(!fEntries){ | |
273 | AliError("No trending map loaded."); | |
274 | return kFALSE; | |
275 | } | |
276 | AliWarning("*** EXPERT FUNCTION *** This function is modifying one trending value to the current DB. Continue if you know what yout do!"); | |
277 | ||
95d47440 | 278 | AliTRDtrendValue *fValue(NULL); |
279 | if(!(fValue = GetValue(name))) { | |
847569f2 | 280 | AliError(Form("Missing trending value %s", name)); |
3240bb4a | 281 | return kFALSE; |
282 | } | |
283 | ||
847569f2 | 284 | fValue->SetTitle(title); |
285 | fValue->Set(mean, sgm); | |
3240bb4a | 286 | if(messages){ |
847569f2 | 287 | for(Int_t ilevel(AliTRDtrendValue::kNlevels); ilevel--;) fValue->SetAlarm(ilevel, messages[ilevel]); |
3240bb4a | 288 | } |
289 | TString s; | |
290 | TObjArray *r(NULL); | |
291 | if(responsible){ | |
292 | s=responsible; | |
293 | r=s.Tokenize("/"); | |
294 | if(r->GetEntriesFast()!=2){ | |
295 | AliWarning("Responsible name/email incorrectly formated."); | |
296 | } else { | |
847569f2 | 297 | fValue->SetResponsible(((TObjString*)r->At(0))->String().Data(), ((TObjString*)r->At(1))->String().Data()); |
3240bb4a | 298 | } |
dffc3357 | 299 | r->Delete(); delete r; |
3240bb4a | 300 | } |
301 | if(notifiables){ | |
302 | s=notifiables; | |
303 | TObjArray *n=s.Tokenize(","); | |
304 | for(Int_t in(0); in<TMath::Min(AliTRDtrendValue::kNnotifiable, n->GetEntriesFast()); in++){ | |
305 | TString ss(((TObjString*)n->At(in))->String()); | |
306 | r=ss.Tokenize("/"); | |
307 | if(r->GetEntriesFast()!=2){ | |
308 | AliWarning(Form("Notifiable person name/email incorrectly formated for [%s].", ss.Data())); | |
309 | } else { | |
847569f2 | 310 | fValue->SetNotifiable(((TObjString*)r->At(0))->String().Data(), ((TObjString*)r->At(1))->String().Data()); |
3240bb4a | 311 | } |
dffc3357 | 312 | r->Delete(); delete r; |
3240bb4a | 313 | } |
dffc3357 | 314 | n->Delete(); delete n; |
3240bb4a | 315 | } |
316 | return kTRUE; | |
317 | } | |
318 | ||
319 | //____________________________________________ | |
320 | void AliTRDtrendingManager::Print(Option_t *o) const | |
321 | { | |
61f6b45e | 322 | // Dump trend value list |
3240bb4a | 323 | if(!fEntries){ |
324 | AliError("No trending map available."); | |
325 | return; | |
326 | } | |
327 | ||
328 | for(Int_t iv(0); iv<fEntries->GetEntriesFast(); iv++){ | |
329 | ((AliTRDtrendValue*)fEntries->At(iv))->Print(o); | |
330 | } | |
331 | } | |
332 | ||
333 | //____________________________________________ | |
847569f2 | 334 | void AliTRDtrendingManager::Load(const char *fn) |
3240bb4a | 335 | { |
847569f2 | 336 | // Load TRD trending DB from $ALICE_ROOT/PWGPP/TRD/data. |
3240bb4a | 337 | |
847569f2 | 338 | AliDebug(1, "Loading TRD trending ..."); |
339 | if(!TFile::Open(fn)) return; | |
3240bb4a | 340 | |
847569f2 | 341 | TList *tvList = gFile->GetListOfKeys(); TIterator *iter(tvList->MakeIterator()); AliTRDtrendValue *tv(NULL); |
95d47440 | 342 | MakeList(tvList->GetEntries()); |
847569f2 | 343 | TKey *ktv(NULL); |
344 | while((ktv = (TKey*)iter->Next())){ | |
345 | tv = (AliTRDtrendValue*)gFile->Get(ktv->GetName()); | |
346 | fEntries->AddLast(new AliTRDtrendValue(*tv)); | |
95d47440 | 347 | delete tv; |
3240bb4a | 348 | } |
95d47440 | 349 | gFile->Close(); |
350 | } | |
351 | ||
352 | //____________________________________________ | |
353 | void AliTRDtrendingManager::MakeList(Int_t entries) | |
354 | { | |
355 | // allocate trending values array | |
356 | fEntries = new TObjArray(entries); | |
357 | fEntries->SetOwner(); | |
358 | fEntries->SetName("TrendValues"); | |
3240bb4a | 359 | } |