th2polyEurope.C

Go to the documentation of this file.
00001 //This tutorial illustrates how to create an histogram with polygonal
00002 //bins (TH2Poly), fill it and draw it. The initial data are stored
00003 //in TMultiGraphs. They represent the european countries.
00004 //The histogram filling is done according to a Mercator projection,
00005 //therefore the bin contains should be proportional to the real surface
00006 //of the countries.
00007 //
00008 //The initial data have been downloaded from: http://www.maproom.psu.edu/dcw/
00009 //This database was developed in 1991/1992 and national boundaries reflect
00010 //political reality as of that time.
00011 //
00012 //The script is shooting npoints (script argument) randomly over the Europe area.
00013 //The number of points inside the countries should be proportional to the country surface
00014 //The estimated surface is compared to the surfaces taken from wikipedia.
00015 //Author: Olivier Couet
00016 
00017 void th2polyEurope(Int_t npoints=500000)
00018 {
00019    Int_t i,j;
00020    Double_t lon1 = -25;
00021    Double_t lon2 =  35;
00022    Double_t lat1 =  34;
00023    Double_t lat2 =  72;
00024    Double_t R = (lat2-lat1)/(lon2-lon1);
00025    Int_t W    = 800;
00026    Int_t H    = (Int_t)(R*800);
00027    gStyle->SetTitleX(0.2);
00028    gStyle->SetStatX(0.28);
00029    gStyle->SetStatY(0.45);
00030    gStyle->SetStatW(0.15);
00031 
00032    // Canvas used to draw TH2Poly (the map)
00033    TCanvas *ce = new TCanvas("ce", "ce",0,0,W,H);
00034    ce->ToggleEventStatus();
00035    ce->SetGridx();
00036    ce->SetGridy();
00037 
00038    // Real surfaces taken from Wikipedia.
00039    const Int_t nx = 36;
00040    // see http://en.wikipedia.org/wiki/Area_and_population_of_European_countries
00041    char *countries[nx] = { "france",     "spain",  "sweden",  "germany",       "finland",
00042                            "norway",     "poland", "italy",   "yugoslavia",    "united_kingdom", 
00043                            "romania",    "belarus","greece",  "czechoslovakia","bulgaria", 
00044                            "iceland",    "hungary","portugal","austria",       "ireland", 
00045                            "lithuania",  "latvia", "estonia", "denmark",       "netherlands",
00046                            "switzerland","moldova","belgium", "albania",       "cyprus", 
00047                            "luxembourg", "andorra","malta",   "liechtenstein", "san_marino", 
00048                            "monaco" };
00049    Float_t surfaces[nx] = { 547030,        505580,   449964,      357021,        338145, 
00050                             324220,        312685,   301230,      255438,        244820, 
00051                             237500,        207600,   131940,      127711,        110910, 
00052                             103000,         93030,    89242,       83870,         70280, 
00053                              65200,         64589,    45226,       43094,         41526, 
00054                              41290,         33843,    30528,       28748,          9250, 
00055                               2586,           468,      316,         160,            61,
00056                                  2};
00057 
00058    TH1F *h = new TH1F("h","Countries surfaces (in km^{2})",3,0,3);
00059    for (i=0; i<nx; i++) h->Fill(countries[i], surfaces[i]);
00060    h->LabelsDeflate();
00061 
00062    TFile::SetCacheFileDir(".");
00063    TFile *f;
00064    f = TFile::Open("http://root.cern.ch/files/europe.root","cacheread");
00065 
00066    TH2Poly *p = new TH2Poly(
00067              "Europe",
00068              "Europe (bin contents are normalized to the surfaces in km^{2})",
00069              lon1,lon2,lat1,lat2);
00070    p->GetXaxis()->SetNdivisions(520);
00071    p->GetXaxis()->SetTitle("longitude");
00072    p->GetYaxis()->SetTitle("latitude");
00073 
00074    p->SetContour(100);
00075 
00076    TMultiGraph *mg;
00077    TKey *key;
00078    TIter nextkey(gDirectory->GetListOfKeys());
00079    while (key = (TKey*)nextkey()) {
00080       obj = key->ReadObj();
00081       if (obj->InheritsFrom("TMultiGraph")) {
00082          mg = (TMultiGraph*)obj;
00083          p->AddBin(mg);
00084       }
00085    }
00086 
00087    TRandom r;
00088    Double_t longitude, latitude;
00089    Double_t x, y, pi4 = TMath::Pi()/4, alpha = TMath::Pi()/360;
00090    
00091    gBenchmark->Start("Partitioning");
00092    p->ChangePartition(100, 100);
00093    gBenchmark->Show("Partitioning");
00094 
00095    // Fill TH2Poly according to a Mercator projection.
00096    gBenchmark->Start("Filling");
00097    for (i=0; i<npoints; i++) {
00098       longitude = r.Uniform(lon1,lon2);
00099       latitude  = r.Uniform(lat1,lat2);
00100       x         = longitude;
00101       y         = 38*TMath::Log(TMath::Tan(pi4+alpha*latitude));
00102       p->Fill(x,y);
00103    }
00104    gBenchmark->Show("Filling");
00105 
00106    Int_t nbins = p->GetNumberOfBins();
00107    Double_t maximum = p->GetMaximum();
00108 
00109 
00110    // h2 contains the surfaces computed from TH2Poly.
00111    TH1F *h2 = h->Clone("h2");
00112    h2->Reset();
00113    for (j=0; j<nx; j++) {
00114       for (i=0; i<nbins; i++) {
00115          if (strstr(countries[j],p->GetBinName(i+1))) {
00116             h2->Fill(countries[j],p->GetBinContent(i+1));
00117             h2->SetBinError(j, p->GetBinError(i+1));
00118          }
00119       }
00120    }
00121 
00122    // Normalize the TH2Poly bin contents to the real surfaces.
00123    Double_t scale = surfaces[0]/maximum;
00124    for (i=0; i<nbins; i++) p->SetBinContent(i+1, scale*p->GetBinContent(i+1));
00125 
00126    gStyle->SetOptStat(1111);
00127    gStyle->SetPalette(1);
00128    p->Draw("COLZ");
00129 
00130    TCanvas *c1 = new TCanvas("c1", "c1",W+10,0,W-20,H);
00131    c1->SetRightMargin(0.047);
00132 
00133    Double_t scale = h->GetMaximum()/h2->GetMaximum();
00134 
00135    h->SetStats(0);
00136    h->SetLineColor(kRed-3);
00137    h->SetLineWidth(2);
00138    h->SetMarkerStyle(20);
00139    h->SetMarkerColor(kBlue);
00140    h->SetMarkerSize(0.8);
00141    h->Draw("LP");
00142    h->GetXaxis()->SetLabelFont(42);
00143    h->GetXaxis()->SetLabelSize(0.03);
00144    h->GetYaxis()->SetLabelFont(42);
00145 
00146    h2->Scale(scale);
00147    Double_t scale2=TMath::Sqrt(scale);
00148    for (i=0; i<nx; i++) h2->SetBinError(i+1, scale2*h2->GetBinError(i+1));
00149    h2->Draw("E SAME");
00150    h2->SetMarkerStyle(20);
00151    h2->SetMarkerSize(0.8);
00152 
00153    TLegend *leg = new TLegend(0.5,0.67,0.92,0.8,NULL,"NDC");
00154    leg->SetTextFont(42);
00155    leg->SetTextSize(0.025);
00156    leg->AddEntry(h,"Real countries surfaces from Wikipedia (in km^{2})","lp");
00157    leg->AddEntry(h2,"Countries surfaces from TH2Poly (with errors)","lp");
00158    leg->Draw();
00159    leg->Draw();
00160    
00161    Double_t wikiSum = h->Integral();
00162    Double_t polySum = h2->Integral();
00163    Double_t error = TMath::Abs(wikiSum-polySum)/wikiSum;
00164    printf("THPoly Europe surface estimation error wrt wikipedia = %f per cent when using %d points\n",100*error,npoints);
00165 }

Generated on Tue Jul 5 15:44:29 2011 for ROOT_528-00b_version by  doxygen 1.5.1