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