ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/benhoob/HWW/network.C
Revision: 1.1
Committed: Mon Feb 14 12:39:14 2011 UTC (14 years, 3 months ago) by benhoob
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Log Message:
Initial commit

File Contents

# User Rev Content
1 benhoob 1.1 #include "TArrow.h"
2     #include "TEllipse.h"
3     #include "TPaveLabel.h"
4     #include "TCanvas.h"
5     #include "TH2F.h"
6     #include "TFile.h"
7     #include "TString.h"
8     #include "TDirectory.h"
9     #include "TKey.h"
10     #include "TText.h"
11    
12     #include "tmvaglob.C"
13    
14     // this macro prints out a neural network generated by MethodMLP graphically
15     // @author: Matt Jachowski, jachowski@stanford.edu
16    
17     TFile* Network_GFile = 0;
18    
19     static Int_t c_DarkBackground = TColor::GetColor( "#6e7a85" );
20    
21     void draw_layer_labels( Int_t nLayers );
22     void draw_layer ( TCanvas* c, TH2F* h, Int_t iHist, Int_t nLayers, Double_t maxWeight );
23     void draw_synapse ( Double_t cx1, Double_t cy1, Double_t cx2, Double_t cy2,
24     Double_t rad1, Double_t rad2, Double_t weightNormed );
25     TString* get_var_names ( Int_t nVars );
26    
27     Bool_t MovieMode = kFALSE;
28    
29     void draw_network( TFile* f, TDirectory* d, const TString& hName = "weights_hist",
30     Bool_t movieMode = kFALSE, const TString& epoch = "" )
31     {
32     Bool_t __PRINT_LOGO__ = kTRUE;
33     Network_GFile = f;
34    
35     MovieMode = movieMode;
36     if (MovieMode) c_DarkBackground = TColor::GetColor( "#707F7F" );
37    
38     // create canvas
39     TStyle* TMVAStyle = gROOT->GetStyle("TMVA"); // the TMVA style
40     Int_t canvasColor = TMVAStyle->GetCanvasColor(); // backup
41     TMVAStyle->SetCanvasColor( c_DarkBackground );
42    
43     Int_t titleFillColor = TMVAStyle->GetTitleFillColor();
44     Int_t titleTextColor = TMVAStyle->GetTitleTextColor();
45     Int_t borderSize = TMVAStyle->GetTitleBorderSize();
46    
47     TMVAStyle->SetTitleFillColor( c_DarkBackground );
48     TMVAStyle->SetTitleTextColor( TColor::GetColor( "#FFFFFF" ) );
49     TMVAStyle->SetTitleBorderSize( 0 );
50    
51     static Int_t icanvas = -1;
52     Int_t ixc = 100 + (icanvas)*40;
53     Int_t iyc = 0 + (icanvas+1)*20;
54     if (MovieMode) ixc = iyc = 0;
55     TString canvasnumber = Form( "c%i", icanvas );
56     TString canvastitle = Form("Neural Network Layout for: %s", d->GetName());
57     TCanvas* c = new TCanvas( canvasnumber, canvastitle,
58     ixc, 0 + (icanvas+1)*20, 1000, 650 );
59     icanvas++;
60     TIter next = d->GetListOfKeys();
61     TKey *key( 0 );
62     Int_t numHists = 0;
63    
64     // loop over all histograms with hName in name again
65     next.Reset();
66     Double_t maxWeight = 0;
67     // find max weight
68     while ((key = (TKey*)next())) {
69    
70     TClass *cl = gROOT->GetClass(key->GetClassName());
71     if (!cl->InheritsFrom("TH2F")) continue;
72    
73     TH2F* h = (TH2F*)key->ReadObj();
74     if (!h) {
75     cout << "Big troubles in \"draw_network\" (1)" << endl;
76     exit(1);
77     }
78     if (TString(h->GetName()).Contains( hName )){
79     numHists++;
80    
81     Int_t n1 = h->GetNbinsX();
82     Int_t n2 = h->GetNbinsY();
83     for (Int_t i = 0; i < n1; i++) {
84     for (Int_t j = 0; j < n2; j++) {
85     Double_t weight = TMath::Abs(h->GetBinContent(i+1, j+1));
86     if (maxWeight < weight) maxWeight = weight;
87     }
88     }
89     }
90     }
91     if (numHists == 0) {
92     cout << "Error: could not find histograms" << endl;
93     //exit(1);
94     }
95    
96     // draw network
97     next.Reset();
98     //cout << "check4a" << endl;
99    
100     Int_t count = 0;
101     while ((key = (TKey*)next())) {
102     //cout << "check4b" << endl;
103    
104     TClass *cl = gROOT->GetClass(key->GetClassName());
105     if (!cl->InheritsFrom("TH2F")) continue;
106     //cout << "check4c" << endl;
107    
108     TH2F* h = (TH2F*)key->ReadObj();
109     //cout << (h->GetName()) << endl;
110     if (!h) {
111     cout << "Big troubles in \"draw_network\" (2)" << endl;
112     exit(1);
113     }
114     //cout << (h->GetName()) << endl;
115     if (TString(h->GetName()).Contains( hName )) {
116     //cout << (h->GetName()) << endl;
117     draw_layer(c, h, count++, numHists+1, maxWeight);
118     }
119     //cout << "check4d" << endl;
120    
121     }
122     draw_layer_labels(numHists+1);
123    
124     // add epoch
125     if (MovieMode) {
126     TText* t = new TText();
127     t->SetTextSize( 0.04 );
128     t->SetTextColor( 0 );
129     t->SetTextAlign( 31 );
130     t->DrawTextNDC( 1 - c->GetRightMargin(), 1 - c->GetTopMargin() - 0.033,
131     Form( "Epoch: %s", epoch.Data() ) );
132     }
133    
134     // ============================================================
135     if (__PRINT_LOGO__) TMVAGlob::plot_logo();
136     // ============================================================
137    
138     c->Update();
139     if (MovieMode) {
140     // save to file
141     TString dirname = "movieplots";
142     TString foutname = dirname + "/" + hName;
143     foutname.Resize( foutname.Length()-5 );
144     foutname.ReplaceAll("epochmonitoring___","");
145     foutname += ".gif";
146    
147     cout << "storing file: " << foutname << endl;
148     c->Print(foutname);
149     c->Clear();
150     delete c;
151     }
152     else {
153     TString fname = "plots/network";
154     TMVAGlob::imgconv( c, fname );
155     }
156    
157     // reset global style changes so that it does not affect other plots
158     TMVAStyle->SetCanvasColor ( canvasColor );
159     TMVAStyle->SetTitleFillColor ( titleFillColor );
160     TMVAStyle->SetTitleTextColor ( titleTextColor );
161     TMVAStyle->SetTitleBorderSize( borderSize );
162    
163     }
164    
165     void draw_layer_labels(Int_t nLayers)
166     {
167     const Double_t LABEL_HEIGHT = 0.032;
168     const Double_t LABEL_WIDTH = 0.20;
169     Double_t effWidth = 0.8*(1.0-LABEL_WIDTH)/nLayers;
170     Double_t height = 0.8*LABEL_HEIGHT;
171     Double_t margY = LABEL_HEIGHT - height;
172    
173     for (Int_t i = 0; i < nLayers; i++) {
174     TString label = Form("Layer %i", i);
175     if (i == nLayers-1) label = "Output layer";
176     Double_t cx = i*(1.0-LABEL_WIDTH)/nLayers+1.0/(2.0*nLayers)+LABEL_WIDTH;
177     Double_t x1 = cx-0.8*effWidth/2.0;
178     Double_t x2 = cx+0.8*effWidth/2.0;
179     Double_t y1 = margY;
180     Double_t y2 = margY + height;
181    
182     TPaveLabel *p = new TPaveLabel(x1, y1, x2, y2, label+"", "br");
183     p->SetFillColor(gStyle->GetTitleFillColor());
184     p->SetTextColor(gStyle->GetTitleTextColor());
185     p->SetFillStyle(1001);
186     p->SetBorderSize( 0 );
187     p->Draw();
188     }
189     }
190    
191     void draw_input_labels(Int_t nInputs, Double_t* cy,
192     Double_t rad, Double_t layerWidth)
193     {
194     const Double_t LABEL_HEIGHT = 0.04;
195     const Double_t LABEL_WIDTH = 0.20;
196     Double_t width = LABEL_WIDTH + (layerWidth-4*rad);
197     Double_t margX = 0.01;
198     Double_t effHeight = 0.8*LABEL_HEIGHT;
199    
200     TString *varNames = get_var_names(nInputs);
201     if (varNames == 0) exit(1);
202    
203     TString input;
204    
205     for (Int_t i = 0; i < nInputs; i++) {
206     if (i != nInputs-1) input = varNames[i];
207     else input = "Bias node";
208     Double_t x1 = margX;
209     Double_t x2 = margX + width;
210     Double_t y1 = cy[i] - effHeight;
211     Double_t y2 = cy[i] + effHeight;
212    
213     TText* t = new TText();
214     t->SetTextColor(gStyle->GetTitleTextColor());
215     t->SetTextAlign(31);
216     t->SetTextSize(LABEL_HEIGHT);
217     if (i == nInputs-1) t->SetTextColor( TColor::GetColor( "#AFDCEC" ) );
218     t->DrawText( x2, y1+0.018, input + " :");
219     }
220    
221     delete[] varNames;
222     }
223    
224     TString* get_var_names( Int_t nVars )
225     {
226     const TString directories[6] = { "InputVariables_NoTransform",
227     "InputVariables_DecorrTransform",
228     "InputVariables_PCATransform",
229     "InputVariables_Id",
230     "InputVariables_Norm",
231     "InputVariables_Deco"};
232    
233     TDirectory* dir = 0;
234     for (Int_t i=0; i<6; i++) {
235     dir = (TDirectory*)Network_GFile->Get( directories[i] );
236     if (dir != 0) break;
237     }
238     if (dir==0) {
239     cout << "*** Big troubles in macro \"network.C\": could not find directory for input variables, "
240     << "and hence could not determine variable names --> abort" << endl;
241     return 0;
242     }
243     dir->cd();
244    
245     TString* vars = new TString[nVars];
246     Int_t ivar = 0;
247    
248     // loop over all objects in directory
249     TIter next(dir->GetListOfKeys());
250     TKey* key = 0;
251     while ((key = (TKey*)next())) {
252     if (key->GetCycle() != 1) continue;
253    
254     if (!TString(key->GetName()).Contains("__S") &&
255     !TString(key->GetName()).Contains("__r") &&
256     !TString(key->GetName()).Contains("Regression"))
257     continue;
258     if (TString(key->GetName()).Contains("target"))
259     continue;
260    
261     // make sure, that we only look at histograms
262     TClass *cl = gROOT->GetClass(key->GetClassName());
263     if (!cl->InheritsFrom("TH1")) continue;
264     TH1 *sig = (TH1*)key->ReadObj();
265     TString hname = sig->GetTitle();
266    
267     vars[ivar] = hname; ivar++;
268    
269     if (ivar > nVars-1) break;
270     }
271    
272     if (ivar != nVars-1) { // bias layer and targets are also in nVars counts
273     cout << "*** Troubles in \"network.C\": did not reproduce correct number of "
274     << "input variables: " << ivar << " != " << nVars << endl;
275     }
276    
277     return vars;
278     }
279    
280     void draw_activation(TCanvas* c, Double_t cx, Double_t cy,
281     Double_t radx, Double_t rady, Int_t whichActivation)
282     {
283     TImage *activation = NULL;
284    
285     switch (whichActivation) {
286     case 0:
287     activation = TImage::Open("sigmoid-small.png");
288     break;
289     case 1:
290     activation = TImage::Open("line-small.png");
291     break;
292     default:
293     cout << "Activation index " << whichActivation << " is not known." << endl;
294     cout << "You messed up or you need to modify network.C to introduce a new "
295     << "activation function (and image) corresponding to this index" << endl;
296     }
297    
298     if (activation == NULL) {
299     cout << "Could not create an image... exit" << endl;
300     return;
301     }
302    
303     activation->SetConstRatio(kFALSE);
304    
305     radx *= 0.7;
306     rady *= 0.7;
307     TString name = Form("activation%f%f", cx, cy);
308     TPad* p = new TPad(name+"", name+"", cx-radx, cy-rady, cx+radx, cy+rady);
309    
310     p->Draw();
311     p->cd();
312    
313     activation->Draw();
314     c->cd();
315     }
316    
317     void draw_layer(TCanvas* c, TH2F* h, Int_t iHist,
318     Int_t nLayers, Double_t maxWeight)
319     {
320     const Double_t MAX_NEURONS_NICE = 12;
321     const Double_t LABEL_HEIGHT = 0.03;
322     const Double_t LABEL_WIDTH = 0.20;
323     Double_t ratio = ((Double_t)(c->GetWindowHeight())) / c->GetWindowWidth();
324     Double_t rad, cx1, *cy1, cx2, *cy2;
325    
326     // this is the smallest radius that will still display the activation images
327     rad = 0.04*650/c->GetWindowHeight();
328    
329     Int_t nNeurons1 = h->GetNbinsX();
330     cx1 = iHist*(1.0-LABEL_WIDTH)/nLayers + 1.0/(2.0*nLayers) + LABEL_WIDTH;
331     cy1 = new Double_t[nNeurons1];
332    
333     Int_t nNeurons2 = h->GetNbinsY();
334     cx2 = (iHist+1)*(1.0-LABEL_WIDTH)/nLayers + 1.0/(2.0*nLayers) + LABEL_WIDTH;
335     cy2 = new Double_t[nNeurons2];
336    
337     Double_t effRad1 = rad;
338     if (nNeurons1 > MAX_NEURONS_NICE)
339     effRad1 = 0.8*(1.0-LABEL_HEIGHT)/(2.0*nNeurons1);
340    
341     for (Int_t i = 0; i < nNeurons1; i++) {
342     cy1[nNeurons1-i-1] = i*(1.0-LABEL_HEIGHT)/nNeurons1 + 1.0/(2.0*nNeurons1) + LABEL_HEIGHT;
343    
344     if (iHist == 0) {
345    
346     TEllipse *ellipse = new TEllipse( cx1, cy1[nNeurons1-i-1],
347     effRad1*ratio, effRad1, 0, 360, 0 );
348     ellipse->SetFillColor(TColor::GetColor( "#fffffd" ));
349     ellipse->SetFillStyle(1001);
350     ellipse->Draw();
351    
352     if (i == 0) ellipse->SetLineColor(9);
353    
354     if (nNeurons1 > MAX_NEURONS_NICE) continue;
355    
356     Int_t whichActivation = 0;
357     if (iHist==0 || iHist==nLayers-1 || i==0) whichActivation = 1;
358     draw_activation(c, cx1, cy1[nNeurons1-i-1],
359     rad*ratio, rad, whichActivation);
360     }
361     }
362    
363     if (iHist == 0) draw_input_labels(nNeurons1, cy1, rad, (1.0-LABEL_WIDTH)/nLayers);
364    
365     Double_t effRad2 = rad;
366     if (nNeurons2 > MAX_NEURONS_NICE)
367     effRad2 = 0.8*(1.0-LABEL_HEIGHT)/(2.0*nNeurons2);
368    
369     for (Int_t i = 0; i < nNeurons2; i++) {
370     cy2[nNeurons2-i-1] = i*(1.0-LABEL_HEIGHT)/nNeurons2 + 1.0/(2.0*nNeurons2) + LABEL_HEIGHT;
371    
372     TEllipse *ellipse =
373     new TEllipse(cx2, cy2[nNeurons2-i-1], effRad2*ratio, effRad2, 0, 360, 0);
374     ellipse->SetFillColor(TColor::GetColor( "#fffffd" ));
375     ellipse->SetFillStyle(1001);
376     ellipse->Draw();
377    
378     if (i == 0 && nNeurons2 > 1) ellipse->SetLineColor(9);
379    
380     if (nNeurons2 > MAX_NEURONS_NICE) continue;
381    
382     Int_t whichActivation = 0;
383     if (iHist+1==0 || iHist+1==nLayers-1 || i==0) whichActivation = 1;
384     draw_activation(c, cx2, cy2[nNeurons2-i-1], rad*ratio, rad, whichActivation);
385     }
386    
387     for (Int_t i = 0; i < nNeurons1; i++) {
388     for (Int_t j = 0; j < nNeurons2; j++) {
389     draw_synapse(cx1, cy1[i], cx2, cy2[j], effRad1*ratio, effRad2*ratio,
390     h->GetBinContent(i+1, j+1)/maxWeight);
391     }
392     }
393    
394     delete [] cy1;
395     delete [] cy2;
396     }
397    
398     void draw_synapse(Double_t cx1, Double_t cy1, Double_t cx2, Double_t cy2,
399     Double_t rad1, Double_t rad2, Double_t weightNormed)
400     {
401     const Double_t TIP_SIZE = 0.01;
402     const Double_t MAX_WEIGHT = 8;
403     const Double_t MAX_COLOR = 100; // red
404     const Double_t MIN_COLOR = 60; // blue
405    
406     if (weightNormed == 0) return;
407    
408     // gStyle->SetPalette(100, NULL);
409    
410     TArrow *arrow = new TArrow(cx1+rad1, cy1, cx2-rad2, cy2, TIP_SIZE, ">");
411     arrow->SetFillColor(1);
412     arrow->SetFillStyle(1001);
413     arrow->SetLineWidth((Int_t)(TMath::Abs(weightNormed)*MAX_WEIGHT+0.5));
414     arrow->SetLineColor((Int_t)((weightNormed+1.0)/2.0*(MAX_COLOR-MIN_COLOR)+MIN_COLOR+0.5));
415     arrow->Draw();
416     }
417    
418     // input: - Input file (result from TMVA),
419     // - use of TMVA plotting TStyle
420     void network( TString fin = "TMVA.root", Bool_t useTMVAStyle = kTRUE )
421     {
422     // set style and remove existing canvas'
423     TMVAGlob::Initialize( useTMVAStyle );
424    
425     // checks if file with name "fin" is already open, and if not opens one
426     TFile* file = TMVAGlob::OpenFile( fin );
427     TIter next(file->GetListOfKeys());
428     TKey *key(0);
429     while( (key = (TKey*)next()) ) {
430     if (!TString(key->GetName()).BeginsWith("Method_MLP")) continue;
431     if( ! gROOT->GetClass(key->GetClassName())->InheritsFrom("TDirectory") ) continue;
432    
433     cout << "--- Found directory: " << ((TDirectory*)key->ReadObj())->GetName() << endl;
434    
435     TDirectory* mDir = (TDirectory*)key->ReadObj();
436    
437     TIter keyIt(mDir->GetListOfKeys());
438     TKey *titkey;
439     while((titkey = (TKey*)keyIt())) {
440     if( ! gROOT->GetClass(titkey->GetClassName())->InheritsFrom("TDirectory") ) continue;
441    
442     TDirectory* dir = (TDirectory *)titkey->ReadObj();
443     dir->cd();
444     TList titles;
445     UInt_t ni = TMVAGlob::GetListOfTitles( dir, titles );
446     if (ni==0) {
447     cout << "No titles found for Method_MLP" << endl;
448     return;
449     }
450     draw_network( file, dir );
451     }
452     }
453    
454     return;
455     }
456