Index: trunk/MagicSoft/Mars/datacenter/macros/plotstat.C
===================================================================
--- trunk/MagicSoft/Mars/datacenter/macros/plotstat.C	(revision 7530)
+++ trunk/MagicSoft/Mars/datacenter/macros/plotstat.C	(revision 7530)
@@ -0,0 +1,549 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz, 02/2006 <mailto:tbretz@astro.uni-wuerzburg.de>
+!   Author(s): Daniela Dorner, 02/2006 <mailto:dorner@astro.uni-wuerzburg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2006
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// plotstat.C
+// ==========
+//
+// This macro is used to plot processing statistics from the db.
+// 
+// Make sure, that database and password are corretly set in a resource
+// file called sql.rc and the resource file is found.
+//
+/////////////////////////////////////////////////////////////////////////////
+#include <iostream>
+#include <iomanip>
+
+#include <TH1.h>
+#include <TEnv.h>
+#include <TPad.h>
+#include <TLine.h>
+#include <TText.h>
+#include <TCanvas.h>
+#include <TLegend.h>
+#include <TPaveText.h>
+#include <TEllipse.h>
+#include <TSQLRow.h>
+#include <TSQLResult.h>
+
+#include "MH.h"
+#include "MTime.h"
+#include "MBinning.h"
+#include "MSQLServer.h"
+#include "MStatusDisplay.h"
+
+using namespace std;
+
+Double_t GetTime(MSQLServer &serv, TString query, TString from="", TString to="")
+{
+    if (!from.IsNull())
+    {
+        if (!query.Contains("where", TString::kIgnoreCase))
+            query += " where ";
+        else
+            query += " and ";
+
+        query += " fRunStart>'";
+        query += from;
+        query += "' and fRunStart<'";
+        query += to;
+        query += "'";
+    }
+
+    TSQLResult *res = serv.Query(query);
+    if (!res)
+    {
+        cout << "ERROR - Query failed: " << query << endl;
+        return -1;
+    }
+
+    TSQLRow *row=res->Next();
+    if (!row)
+    {
+        cout << "ERROR - Query " << query << " empty." << endl;
+        delete res;
+        return -1;
+    }
+
+    const char *time = (*row)[0];
+
+    delete res;
+    return time ? atof(time) : 0;
+}
+
+void DrawYears()
+{
+    UInt_t year   = 2004;
+    Int_t  period = 0;
+
+    MTime past, from, now(-1);
+    past.Set(2004, 1, 1, 13, 1);
+
+    TLine l;
+    l.SetLineStyle(kDotted);
+    l.SetLineColor(kWhite);
+    while (past<now)
+    {
+        if (period!=past.GetMagicPeriod())
+        {
+            period = past.GetMagicPeriod();
+            from = past;
+        }
+
+        if (past.Year()!=year)
+        {
+            Double_t dx = (past.GetMjd()-from.GetMjd())/28;
+            l.DrawLine(past.GetMagicPeriod()+dx, 0,
+                       past.GetMagicPeriod()+dx, gPad->GetUymax());
+            year = past.Year();
+        }
+        past.SetMjd(past.GetMjd()+1);
+    }
+}
+
+void DrawCake(TH1F *h, Int_t p0=-1, Int_t p1=9999)
+{
+    gPad->Range(-1, -0.9, 1, 1.1);
+
+    gPad->SetFillColor(kWhite);
+    gPad->SetBorderMode(0);
+    gPad->SetFrameBorderMode(0);
+
+    const Double_t r1 = 0.8;
+    const Double_t r2 = 0.59;
+
+    const Double_t tot0 = h[0].Integral(p0, p1);
+    const Double_t tot1 = h[1].Integral(p0, p1);
+    const Double_t tot2 = h[2].Integral(p0, p1);
+    const Double_t tot3 = h[3].Integral(p0, p1);
+    const Double_t tot4 = h[4].Integral(p0, p1);
+    const Double_t tot5 = h[5].Integral(p0, p1);
+    const Double_t tot6 = h[6].Integral(p0, p1);
+    const Double_t tot7 = h[7].Integral(p0, p1);
+
+    TString title = Form("Total = %.1fh (excl=%.1fh)", tot1, tot1-tot2);
+
+    if (p0>0 && p1<9000 && p0==p1)
+        title.Prepend(Form("P%d: ", TMath::Nint(h[0].GetBinCenter(p0))));
+
+    TPaveText *pave = new TPaveText(-0.99, 0.92, 0.99, 1.09);
+    pave->SetBorderSize(1);
+    pave->AddText(title)->SetTextAlign(22);
+    pave->SetBit(kCanDelete);
+    pave->Draw();
+
+    if (tot1<0.1)
+        return;
+
+    TEllipse e;
+    e.SetFillColor(15);
+    //e.SetLineColor(15);
+    e.DrawEllipse(0, 0, r1*1.1, r2*1.1, 90, tot0/tot1*360+90, 0);
+
+    //    0    : hollow
+    //    1001 : Solid
+    //    2001 : hatch style
+    //    3000+pattern_number (see below)
+    //    4000 :the window is transparent.
+    //    4000 to 4100 the window is 100% transparent to 100% opaque
+
+    e.SetLineColor(10);//17);
+    e.SetFillColor(10);//17);
+    e.DrawEllipse(0, 0, r1, r2, 0, 360, 0);
+    e.SetLineColor(kBlack);
+
+    e.SetFillColor(kBlack);
+    e.DrawEllipse(0, 0, r1, r2, 90, tot2/tot1*360+90, 0);
+    //e.SetLineColor(kBlue);
+    e.SetFillColor(kBlue);
+    e.DrawEllipse(0, 0, r1, r2, 90, tot3/tot1*360+90, 0);
+    //e.SetLineColor(kRed);
+    e.SetFillColor(kRed);
+    e.DrawEllipse(0, 0, r1, r2, 90, tot4/tot1*360+90, 0);
+    //e.SetLineColor(kGreen);
+    e.SetFillColor(kGreen);
+    e.DrawEllipse(0, 0, r1, r2, 90, tot5/tot1*360+90, 0);
+    //e.SetLineColor(kRed+100);
+    e.SetFillColor(kRed+100);
+    e.DrawEllipse(0, 0, r1, r2, 90, tot6/tot1*360+90, 0);
+    //e.SetLineColor(kGreen+100);
+    e.SetFillColor(kGreen+100);
+    e.DrawEllipse(0, 0, r1, r2, 90, tot7/tot1*360+90, 0);
+
+    TText txt;
+    txt.SetTextSize(0.08);
+
+    txt.SetTextAlign(32);
+
+    txt.SetTextColor(kBlack);
+    txt.DrawText(0.99, 0.65,    Form("%.1f%%", (tot2-tot3)/tot1*100));
+    txt.SetTextColor(kBlue);
+    txt.DrawText(0.99, -0.58,   Form("%.1f%%", (tot3-tot4)/tot1*100));
+    txt.SetTextColor(kRed+100);
+    txt.DrawText(-0.35, -0.70,  Form("%.1f%%", (tot6-tot7)/tot1*100));
+
+    txt.SetTextAlign(12);
+
+    txt.SetTextColor(kBlack);
+    txt.DrawText(0, 0.77,       Form("%.1f%%", (tot1-tot2)/tot1*100));
+    txt.SetTextColor(15);
+    txt.DrawText(-0.99, 0.65,   Form("%.1f%%", tot0/tot1*100));
+    txt.SetTextColor(kGreen+100);
+    txt.DrawText(-0.99, -0.58,  Form("%.1f%%", tot7/tot1*100));
+    txt.SetTextColor(kRed);
+    txt.DrawText(0.35, -0.70,   Form("%.1f%%", (tot4-tot5)/tot1*100));
+
+    txt.SetTextAlign(22);
+
+    txt.SetTextColor(kGreen);
+    txt.DrawText(0, -0.79,      Form("%.1f%%", (tot5-tot6)/tot1*100));
+}
+
+void DrawLegend(TH1F *h)
+{
+    TLegend leg(0.01, 0.12, 0.99, 0.98, "Data Statistics");
+    leg.SetBorderSize(1);
+    leg.SetTextSize(0.1);
+
+    TH1 *hc[8];
+
+    for (int i=0; i<8; i++)
+    {
+        hc[i] = (TH1*)h[i].Clone();
+        hc[i]->SetBit(kCanDelete);
+        hc[i]->SetDirectory(0);
+    }
+
+    leg.AddEntry(hc[0], "Files available",     "L");
+    leg.AddEntry(hc[1], "Excluded data",       "F");
+    leg.AddEntry(hc[2], "Not sequenced",       "F");
+    leg.AddEntry(hc[3], "Callisto not done",   "F");
+    leg.AddEntry(hc[4], "Callisto failed",     "F");
+    leg.AddEntry(hc[5], "Star not done",       "F");
+    leg.AddEntry(hc[6], "Star failed",         "F");
+    leg.AddEntry(hc[7], "Star OK",             "F");
+
+    gROOT->SetSelectedPad(0);
+    leg.DrawClone()->SetBit(kCanDelete);;
+}
+
+Bool_t plot(MStatusDisplay &d, MSQLServer &serv)
+{
+    TString query[8];
+
+    // 0: All data for which are files available
+    query[0]  = "select ";
+    query[0] += "SUM(if(TIME_TO_SEC(fRunStop)-TIME_TO_SEC(fRunStart)<0, ";
+    query[0] += "TIME_TO_SEC(fRunStop)-TIME_TO_SEC(fRunStart)+24*60*60, ";
+    query[0] += "TIME_TO_SEC(fRunStop)-TIME_TO_SEC(fRunStart)))/3600 ";
+    query[0] += "from RunData left join RunProcessStatus on RunData.fRunNumber=RunProcessStatus.fRunNumber ";
+    query[0] += "where fRunTypeKey=2 and ";
+    query[0] += " not ISNULL(fRawFileAvail)";
+
+    // 1: All data
+    query[1]  = "select ";
+    query[1] += "SUM(if(TIME_TO_SEC(fRunStop)-TIME_TO_SEC(fRunStart)<0, ";
+    query[1] += "TIME_TO_SEC(fRunStop)-TIME_TO_SEC(fRunStart)+24*60*60, ";
+    query[1] += "TIME_TO_SEC(fRunStop)-TIME_TO_SEC(fRunStart)))/3600 ";
+    query[1] += "from RunData where fRunTypeKEY=2";
+
+    // 2: All data which is not excluded
+    query[2]  = "select ";
+    query[2] += "SUM(if(TIME_TO_SEC(fRunStop)-TIME_TO_SEC(fRunStart)<0, ";
+    query[2] += "TIME_TO_SEC(fRunStop)-TIME_TO_SEC(fRunStart)+24*60*60, ";
+    query[2] += "TIME_TO_SEC(fRunStop)-TIME_TO_SEC(fRunStart)))/3600 ";
+    query[2] += "from RunData where fRunTypeKEY=2 and fExcludedFDAKEY=1";
+
+    // 3: All sequences
+    query[3]  = "select SUM(fRunTime)/3600 from Sequences";
+
+    // 4: All sequences with callisto failed
+    query[4]  = "select SUM(fRunTime)/3600 from Sequences left join SequenceProcessStatus on ";
+    query[4] += "Sequences.fSequenceFirst=SequenceProcessStatus.fSequenceFirst where ";
+    query[4] += "ISNULL(fCallisto) and not ISNULL(fFailedTime) and not ISNULL(fAllFilesAvail)";
+
+    // 5: All sequences with callisto=OK
+    query[5]  = "select SUM(fRunTime)/3600 from Sequences left join SequenceProcessStatus on ";
+    query[5] += "Sequences.fSequenceFirst=SequenceProcessStatus.fSequenceFirst where not ISNULL(fCallisto)";
+
+    // 6: All sequences with star failed
+    query[6]  = "select SUM(fRunTime)/3600 from Sequences left join SequenceProcessStatus on ";
+    query[6] += "Sequences.fSequenceFirst=SequenceProcessStatus.fSequenceFirst where ";
+    query[6] += "ISNULL(fStar) and not ISNULL(fFailedTime) and not ISNULL(fCallisto)";
+
+    // 7: All sequences with star=OK
+    query[7]  = "select SUM(fRunTime)/3600 from Sequences left join SequenceProcessStatus on ";
+    query[7] += "Sequences.fSequenceFirst=SequenceProcessStatus.fSequenceFirst where not ISNULL(fStar)";
+
+    // 0: All data
+    // 1: All data which is not excluded
+    // 2: All data for which are files available
+    // 3: All sequences
+    // 4: All sequences with callisto=not done
+    // 5: All sequences with callisto not done and failed
+    // 6: All sequences with star=not done
+    // 7: All sequences with star not done and failed
+
+    MTime now(-1);
+    MTime past;
+    past.Set(2004, 1, 1, 13, 1);
+
+    int first=-1;
+    int last =-1;
+
+    if (first<0)
+        first=14;
+    if (last<0)
+        last=now.GetMagicPeriod();
+
+    TH1F h[8];
+
+    MBinning bins(last-first+1, first-0.5, last+0.5);
+    for (int i=0; i<8; i++)
+    {
+        bins.Apply(h[i]);
+        h[i].SetName(Form("H%d", i));
+        h[i].SetDirectory(0);
+    }
+
+    Int_t period = 0;
+    MTime from;
+
+    while (past<now)
+    {
+        if (past.GetMagicPeriod()!=period)
+        {
+            period = past.GetMagicPeriod();
+
+            if (period>=first && period<=last)
+            {
+                TString a = from.GetSqlDateTime();
+                TString b = past.GetSqlDateTime();
+
+                for (int i=0; i<8; i++)
+                    h[i].Fill(period, GetTime(serv, query[i], a, b));
+            }
+
+            from = past;
+
+        }
+        past.SetMjd(past.GetMjd()+1);
+    }
+
+    for (int i=0; i<h[0].GetNbinsX(); i++)
+        h[0].SetBinError(i+1, 0.001);
+
+
+    h[4].Add(&h[5]);
+    h[6].Add(&h[7]);
+
+    TCanvas &c1 = d.AddTab("Hist");
+    c1.SetFillColor(kWhite);
+    c1.Divide(2,2);
+
+    c1.cd(1);
+
+    gPad->SetBorderMode(0);
+    gPad->SetFrameBorderMode(0);
+    gPad->SetFillColor(kWhite);
+    gPad->SetRightMargin(0.01);
+    gPad->SetTopMargin(0.02);
+    gPad->SetLeftMargin(0.09);
+    gPad->SetBottomMargin(0.12);
+    gPad->SetGridy();
+    gPad->SetPad(0, 0.5, 0.75, 1.0);
+
+    h[1].SetBit(TH1::kNoStats);
+    // h[0].GetXaxis()->SetRangeUser(13.5, period+0.5);
+    h[1].GetXaxis()->CenterTitle();
+    h[1].GetXaxis()->SetTitleSize(0.06);
+    h[1].GetYaxis()->SetTitleSize(0.06);
+    h[1].GetYaxis()->SetTitleOffset(0.7);
+    h[1].GetXaxis()->SetLabelSize(0.06);
+    h[1].GetYaxis()->SetLabelSize(0.06);
+    h[1].GetXaxis()->SetNdivisions(550);
+    h[1].SetYTitle("Time [h]");
+    h[1].SetFillColor(kWhite);
+    h[1].SetLineColor(kBlack);
+    h[1].DrawCopy("");
+
+    h[2].SetLineColor(kBlack);
+    h[2].SetFillColor(kBlack);
+    h[2].DrawCopy("Bsame");
+
+    h[3].SetLineColor(kBlue);
+    h[3].SetFillColor(kBlue);
+    h[3].DrawCopy("Bsame");
+
+    h[4].SetLineColor(kRed);
+    h[4].SetFillColor(kRed);
+    h[4].DrawCopy("Bsame");
+
+    h[5].SetLineColor(kGreen);
+    h[5].SetFillColor(kGreen);
+    h[5].DrawCopy("Bsame");
+
+    h[6].SetLineColor(kRed+100);
+    h[6].SetFillColor(kRed+100);
+    h[6].DrawCopy("Bsame");
+
+    h[7].SetLineColor(kGreen+100);
+    h[7].SetFillColor(kGreen+100);
+    h[7].DrawCopy("Bsame");
+
+    h[0].SetMarkerSize(0);
+    h[0].SetMarkerColor(15);
+    h[0].SetLineWidth(3);
+    h[0].SetLineColor(15);
+    h[0].DrawCopy("EPsame");
+
+    gPad->Update();
+    DrawYears();
+
+    c1.cd(4);
+
+    gPad->SetBorderMode(0);
+    gPad->SetFrameBorderMode(0);
+    gPad->SetPad(0.75, 0, 1.0, 0.5);
+
+    DrawCake(h);
+
+    TCanvas &cx = d.AddTab("All");
+    cx.SetBorderMode(0);
+    cx.SetFrameBorderMode(0);
+    cx.SetFillColor(kWhite);
+    cx.Divide(8,4);
+    cx.cd(1);
+    DrawLegend(h);
+
+    for (int i=0; i<h[0].GetNbinsX(); i++)
+    {
+        TCanvas &c = d.AddTab(Form("P%d", TMath::Nint(h[0].GetBinCenter(i+1))));
+
+        c.SetBorderMode(0);
+        c.SetFrameBorderMode(0);
+        c.SetPad(0.25, 0, 0.75, 1.0);
+        c.SetFillColor(kWhite);
+
+        DrawCake(h, i+1, i+1);
+
+        if (i<4*8)
+        {
+            cx.cd(i+2);
+            DrawCake(h, i+1, i+1);
+        }
+    }
+
+    c1.cd(2);
+
+    gPad->SetBorderMode(0);
+    gPad->SetFrameBorderMode(0);
+    gPad->SetRightMargin(0.01);
+    gPad->SetTopMargin(0.02);
+    gPad->SetLeftMargin(0.09);
+    gPad->SetBottomMargin(0.12);
+    gPad->SetPad(0, 0, 0.75, 0.5);
+    gPad->SetGridy();
+
+    h[1].Scale(0.01);
+    h[0].Divide(&h[1]);
+    h[2].Divide(&h[1]);
+    h[3].Divide(&h[1]);
+    h[4].Divide(&h[1]);
+    h[5].Divide(&h[1]);
+    h[6].Divide(&h[1]);
+    h[7].Divide(&h[1]);
+    h[1].Divide(&h[1]);
+    h[1].Scale(100);
+
+    for (int i=0; i<h[0].GetNbinsX(); i++)
+        h[0].SetBinError(i+1, 0.001);
+
+    h[1].GetXaxis()->SetNdivisions(550);
+    h[1].SetYTitle("%");
+    h[1].SetXTitle("Period");
+    h[1].GetYaxis()->SetRangeUser(0, 100);
+
+    h[1].DrawCopy();
+    h[2].DrawCopy("same");
+    h[3].DrawCopy("same");
+    h[4].DrawCopy("same");
+    h[5].DrawCopy("same");
+    h[6].DrawCopy("same");
+    h[7].DrawCopy("same");
+    h[0].DrawCopy("same");
+/*
+    TLine l;
+    l.SetLineColor(kWhite);
+    l.SetLineWidth(1);
+    l.SetLineStyle(kDotted);
+    for (int i=10; i<95; i+=10)
+        l.DrawLine(13.5, i, period+0.5, i);
+    l.SetLineStyle(kSolid);
+    l.DrawLine(13.5, 50, period+0.5, 50);
+ */
+    gPad->Update();
+    DrawYears();
+
+    c1.cd(3);
+
+    gPad->SetBorderMode(0);
+    gPad->SetFrameBorderMode(0);
+    gPad->SetPad(0.75, 0.5, 1.0, 1.0);
+
+    DrawLegend(h);
+
+    return kTRUE;
+}
+
+int plotstat()
+{
+    TEnv env("sql.rc");
+
+    MSQLServer serv(env);
+    if (!serv.IsConnected())
+    {
+        cout << "ERROR - Connection to database failed." << endl;
+        return 0;
+    }
+
+    cout << "plotstat" << endl;
+    cout << "--------" << endl;
+    cout << endl;
+    cout << "Connected to " << serv.GetName() << endl;
+    cout << endl;
+
+    MStatusDisplay *d = new MStatusDisplay;
+    d->SetWindowName(serv.GetName());
+    d->SetTitle(serv.GetName());
+
+    plot(*d, serv);
+
+    //d->SaveAsRoot("plotstat.root");
+    //d->SaveAsPS("plotstat.ps");
+
+    return 1;
+}
