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

# Content
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