Index: trunk/Mars/hawc/quality.C
===================================================================
--- trunk/Mars/hawc/quality.C	(revision 20002)
+++ trunk/Mars/hawc/quality.C	(revision 20003)
@@ -9,4 +9,5 @@
 #include "TText.h"
 #include "TLine.h"
+#include "TStyle.h"
 
 #include "fits.h"
@@ -19,14 +20,16 @@
 #endif
 
-Bool_t Contains(TArrayD **vec, Double_t t0, Double_t range=0)
-{
-    TArrayD *arr0 = vec[0];
-    TArrayD *arr1 = vec[1];
-    TArrayD *arr2 = vec[2];
-
-    for (int i=0; i<arr0->GetSize(); i++)
-    {
-        Double_t start = (*arr1)[i];
-        Double_t stop  = (*arr2)[i];
+#include <numeric>
+
+Bool_t Contains(vector<double> *vec, Double_t t0, Double_t range=0)
+{
+    auto &arr0 = vec[0];
+    auto &arr1 = vec[1];
+    auto &arr2 = vec[2];
+
+    for (size_t i=0; i<arr0.size(); i++)
+    {
+        Double_t start = arr1[i];
+        Double_t stop  = arr2[i];
 
         if (stop>start+305./24/3600)
@@ -34,15 +37,66 @@
 
         if (t0>start-range && t0<stop+range)
-        //{
-        //    if (fmod(t0, 1)>4./24 && fmod(t0,1)<4.1/24)
-        //        cout << t0-start << " " <<t0 << " " << stop-t0 << " " << start-15779 << " " << stop-15779 << " " << (*arr0)[i] << endl;
+        {
+            //if (fmod(t0, 1)>4./24 && fmod(t0,1)<4.1/24)
+            //    cout << t0-start << " " <<t0 << " " << stop-t0 << " " << start-15779 << " " << stop-15779 << " " << (*arr0)[i] << endl;
             return kTRUE;
-        //}
-    }
-
-    return arr0->GetSize()==0;
-}
-
-Int_t PlotThresholds(double start, TArrayD **vec, TString fname)
+        }
+    }
+
+    return arr0.empty();
+}
+
+Int_t ReadRuns(vector<double> *vec, TString fname)
+{
+    fname += ".FAD_CONTROL_RUNS.fits";
+
+    fits file(fname.Data());
+    if (!file)
+    {
+        cerr << fname << ": " << gSystem->GetError() << endl;
+        return -2;
+    }
+
+    //cout << fname << endl;
+
+    Double_t time;
+    uint32_t qos, stats[2];
+
+    if (!file.SetPtrAddress("Time", &time))
+        return -1;
+    if (!file.SetPtrAddress("QoS", &qos))
+        return -1;
+    if (!file.SetPtrAddress("stats", stats))
+        return -1;
+
+    int32_t run = -1;
+    double start=0;
+
+    while (file.GetNextRow())
+    {
+        switch (qos)
+        {
+        case 1:
+            start = time;
+            run = stats[0];
+            break;
+        case 0:
+            if (uint32_t(run)==stats[1] && stats[0]==stats[1])
+            {
+                vec[0].push_back(run);
+                vec[1].push_back(start);
+                vec[2].push_back(time);
+                //cout << setw(3) << ": " << MTime(start) << " -- " << MTime(time) << endl;
+            }
+            run = -1;
+            break;
+        }
+    }
+
+    return 0;
+}
+
+
+Int_t PlotThresholds(double start, vector<double> *vec, TString fname)
 {
     fname += ".FTU_CONTROL_DAC.fits";
@@ -103,5 +157,5 @@
 }
 
-Int_t PlotCurrent(double start, TArrayD **vec, TString fname)
+Int_t PlotCurrent(double start, vector<double> *vec, TString fname)
 {
     fname += ".BIAS_CONTROL_AVERAGE_DATA.fits";
@@ -121,4 +175,5 @@
     Float_t  Tpsu[2];
     Float_t  Vavg[64];
+    Float_t  Uavg[64];
 
     if (!file.SetPtrAddress("Time", &time))
@@ -136,4 +191,13 @@
     if (!file.SetPtrAddress("Vavg", Vavg))
         return -1;
+
+    bool has_uset = true;
+    try
+    {
+        has_uset = file.SetPtrAddress("Uavg", Uavg);
+    }
+    catch (const exception&)
+    {
+    }
 
     TGraph g1;
@@ -141,8 +205,10 @@
     TGraph g3;
     TGraph g4;
+    TGraph g5;
     g1.SetName("CurrentAvg");
     g2.SetName("TemperatureAvg");
     g3.SetName("TempPSUavg");
     g4.SetName("VoltageAvg");
+    g5.SetName("UsetAvg");
 
     while (file.GetNextRow())
@@ -152,4 +218,6 @@
             sort(Tavg, Tavg+64);
             sort(Vavg, Vavg+64);
+            if (has_uset)
+                sort(Uavg, Uavg+64);
 
             g1.SetPoint(g1.GetN(), time*24*3600, Iavg[31]);
@@ -157,4 +225,6 @@
             g3.SetPoint(g3.GetN(), time*24*3600, (Tpsu[0]+Tpsu[1])/2);
             g4.SetPoint(g4.GetN(), time*24*3600, Vavg[31]);
+            if (has_uset)
+                g5.SetPoint(g5.GetN(), time*24*3600, Uavg[31]);
         }
 
@@ -176,5 +246,5 @@
     frame1.GetXaxis()->SetLabelSize(0.12);
     frame1.GetYaxis()->SetLabelSize(0.1);
-    frame1.GetYaxis()->SetTitle("CURRENT");
+    frame1.GetYaxis()->SetTitle("CURRENT [#mu A]");
     frame1.GetYaxis()->CenterTitle();
     frame1.GetYaxis()->SetTitleOffset(0.2);
@@ -203,5 +273,5 @@
     frame4.GetXaxis()->SetLabelSize(0.12);
     frame4.GetYaxis()->SetLabelSize(0.1);
-    frame4.GetYaxis()->SetTitle("VOLTAGE");
+    frame4.GetYaxis()->SetTitle("BIAS VOLTAGE [V]");
     frame4.GetYaxis()->CenterTitle();
     frame4.GetYaxis()->SetTitleOffset(0.2);
@@ -209,9 +279,15 @@
     frame4.DrawCopy();
 
+    if (has_uset)
+    {
+        g5.SetMarkerColor(kBlue);
+        g5.SetMarkerStyle(kFullDotMedium);
+        g5.DrawClone("P");
+    }
+
     g4.SetMarkerStyle(kFullDotMedium);
     g4.DrawClone("P");
 
 
-
     gROOT->SetSelectedPad(0);
     gPad->GetCanvas()->cd(6);
@@ -224,5 +300,5 @@
     TH1C frame2("Temperature_frame", "", 1000, (start+0.45)*24*3600, (start+1.025)*24*3600);
     frame2.SetMinimum(0);
-    frame2.SetMaximum(40);
+    frame2.SetMaximum(65);
     frame2.SetStats(kFALSE);
     frame2.GetXaxis()->SetTimeDisplay(true);
@@ -230,5 +306,5 @@
     frame2.GetXaxis()->SetLabelSize(0.12);
     frame2.GetYaxis()->SetLabelSize(0.1);
-    frame2.GetYaxis()->SetTitle("TEMPERATURE");
+    frame2.GetYaxis()->SetTitle("TEMPERATURE [#circ C]");
     frame2.GetYaxis()->CenterTitle();
     frame2.GetYaxis()->SetTitleOffset(0.2);
@@ -239,5 +315,5 @@
     g2.DrawClone("P");
 
-    g3.SetMarkerColor(kBlue);
+    g3.SetMarkerColor(kRed);
     g3.SetMarkerStyle(kFullDotMedium);
     g3.DrawClone("P");
@@ -246,7 +322,7 @@
 }
 
-Int_t PlotRate(double start, TArrayD **vec, TString fname)
-{
-    fname += ".FTM_CONTROL_DATA.fits";
+Int_t PlotDrsTemp(double /*start*/, vector<double> *vec, TString fname)
+{
+    fname += ".FAD_CONTROL_TEMPERATURE.fits";
 
     fits file(fname.Data());
@@ -260,34 +336,90 @@
 
     Double_t time;
-    uint32_t trg_counter;
-    uint32_t dead_time, run_time;
-
-    if (!file.SetPtrAddress("Time",  &time))
-        return -1;
-
-    if (!file.SetPtrAddress("trg_counter", &trg_counter))
-        return -1;
-    if (!file.SetPtrAddress("dead_time", &dead_time))
-        return -1;
-    if (!file.SetPtrAddress("run_time", &run_time))
+    uint16_t cnt;
+    Float_t  temp[160];
+
+    if (!file.SetPtrAddress("Time", &time))
+        return -1;
+
+    if (!file.SetPtrAddress("cnt", &cnt))
+        return -1;
+
+    if (!file.SetPtrAddress("temp", temp))
         return -1;
 
     TGraph g1, g2;
-    g1.SetName("TriggerRate");
-    g2.SetName("RelOnTime");
-
-    uint32_t prev = 0;
+    g1.SetName("TempDRS1");
+    g2.SetName("TempDRS2");
 
     while (file.GetNextRow())
         if (Contains(vec, time))
         {
-            g1.SetPoint(g1.GetN(), time*24*3600, 1e8*(trg_counter-prev)/(run_time-dead_time));
-            g2.SetPoint(g2.GetN(), time*24*3600, 1.-float(dead_time)/run_time);
-            prev = trg_counter;
+            g1.SetPoint(g1.GetN(), time*24*3600, accumulate(temp,   temp+4, 0.)/4);
+            g2.SetPoint(g2.GetN(), time*24*3600, accumulate(temp+4, temp+8, 0.)/4);
         }
 
 
     gROOT->SetSelectedPad(0);
+    gPad->GetCanvas()->cd(6);
+
+    g1.SetMarkerColor(kBlue);
+    g1.SetMarkerStyle(kFullDotMedium);
+    g1.DrawClone("P");
+
+    g2.SetMarkerColor(kBlue);
+    g2.SetMarkerStyle(kFullDotMedium);
+    g2.DrawClone("P");
+
+    return 0;
+}
+
+Int_t PlotPatchRate(double /*start*/, vector<double> *vec, TString fname)
+{
+    fname += ".FTU_CONTROL_DATA.fits";
+
+    fits file(fname.Data());
+    if (!file)
+    {
+        cerr << fname << ": " << gSystem->GetError() << endl;
+        return -2;
+    }
+
+    //cout << fname << endl;
+
+    Double_t time;
+    uint32_t qos;
+    uint32_t counter_ch[8];
+    float    dt_sec;
+
+    if (!file.SetPtrAddress("QoS",  &qos))
+        return -1;
+    if (!file.SetPtrAddress("Time",  &time))
+        return -1;
+
+    if (!file.SetPtrAddress("counter_ch", counter_ch))
+        return -1;
+    if (!file.SetPtrAddress("dt_sec", &dt_sec))
+        return -1;
+
+    TGraph g1, g2;
+    g1.SetName("MinPatchRate");
+    g2.SetName("MaxPatchRate");
+
+    while (file.GetNextRow())
+        if (Contains(vec, time))
+        {
+            if (qos==0)   // Only automatic reports
+                continue;
+
+            sort(counter_ch, counter_ch+8);
+
+            g1.SetPoint(g1.GetN(), time*24*3600, counter_ch[1]/dt_sec);
+            g2.SetPoint(g2.GetN(), time*24*3600, counter_ch[7]/dt_sec);
+        }
+
+
+    gROOT->SetSelectedPad(0);
     gPad->GetCanvas()->cd(3);
+    /*
     gPad->SetGrid();
     gPad->SetTopMargin(0);
@@ -305,4 +437,85 @@
     frame1.GetYaxis()->SetLabelSize(0.1);
     frame1.GetYaxis()->SetTitle("TRIGGER RATE");
+    frame1.GetYaxis()->CenterTitle();
+    frame1.GetYaxis()->SetTitleOffset(0.2);
+    frame1.GetYaxis()->SetTitleSize(0.1);
+    frame1.DrawCopy();*/
+
+    g1.SetMarkerColor(kGreen);
+    g1.SetMarkerStyle(kFullDotMedium);
+    g1.DrawClone("P");
+
+    g2.SetMarkerColor(kRed);
+    g2.SetMarkerStyle(kFullDotMedium);
+    g2.DrawClone("P");
+
+    return 0;
+}
+
+Int_t PlotCameraRate(double start, vector<double> *vec, TString fname)
+{
+    fname += ".FTM_CONTROL_DATA.fits";
+
+    fits file(fname.Data());
+    if (!file)
+    {
+        cerr << fname << ": " << gSystem->GetError() << endl;
+        return -2;
+    }
+
+    //cout << fname << endl;
+
+    Double_t time;
+    uint32_t trg_counter;
+    uint32_t dead_time, run_time;
+    float temp;
+
+    if (!file.SetPtrAddress("Time",  &time))
+        return -1;
+
+    if (!file.SetPtrAddress("trg_counter", &trg_counter))
+        return -1;
+    if (!file.SetPtrAddress("dead_time", &dead_time))
+        return -1;
+    if (!file.SetPtrAddress("run_time", &run_time))
+        return -1;
+    if (!file.SetPtrAddress("temp", &temp))
+        return -1;
+
+    TGraph g1, g2, g3;
+    g1.SetName("TriggerRate");
+    g2.SetName("RelOnTime");
+    g3.SetName("TempFTM");
+
+
+    uint32_t prev = 0;
+
+    while (file.GetNextRow())
+        if (Contains(vec, time))
+        {
+            g1.SetPoint(g1.GetN(), time*24*3600, 1e8*(trg_counter-prev)/(run_time-dead_time));
+            g2.SetPoint(g2.GetN(), time*24*3600, 1.-float(dead_time)/run_time);
+            g3.SetPoint(g2.GetN(), time*24*3600, temp);
+            prev = trg_counter;
+        }
+
+
+    gROOT->SetSelectedPad(0);
+    gPad->GetCanvas()->cd(3);
+    gPad->SetGrid();
+    gPad->SetTopMargin(0);
+    gPad->SetBottomMargin(0);
+    gPad->SetRightMargin(0.001);
+    gPad->SetLeftMargin(0.04);
+
+    TH1C frame1("Rate_frame", "", 1000, (start+0.45)*24*3600, (start+1.025)*24*3600);
+    frame1.SetMinimum(0);
+    frame1.SetMaximum(90);
+    frame1.SetStats(kFALSE);
+    frame1.GetXaxis()->SetTimeDisplay(true);
+    frame1.GetXaxis()->SetTimeFormat("%H:%M %F1995-01-01 00:00:00 GMT");
+    frame1.GetXaxis()->SetLabelSize(0.12);
+    frame1.GetYaxis()->SetLabelSize(0.1);
+    frame1.GetYaxis()->SetTitle("TRIGGER RATE [Hz]");
     frame1.GetYaxis()->CenterTitle();
     frame1.GetYaxis()->SetTitleOffset(0.2);
@@ -340,8 +553,15 @@
     g2.DrawClone("P");
 
+    gROOT->SetSelectedPad(0);
+    gPad->GetCanvas()->cd(6);
+
+    g3.SetMarkerColor(kGreen);
+    g3.SetMarkerStyle(kFullDotMedium);
+    g3.DrawClone("P");
+
     return 0;
 }
 
-int quality(const char *basepath, UInt_t y=0, UInt_t m=0, UInt_t d=0, const char *outpath=0)
+int quality(const char *basepath="/data/aux", UInt_t y=0, UInt_t m=0, UInt_t d=0, const char *outpath=0, const bool all=true)
 {
     // To get correct dates in the histogram you have to add
@@ -366,9 +586,9 @@
     cout << endl;
 
-    double start = MTime(y, m, d).GetMjd()-40587;
-
-    TArrayD run, beg, end;
-
-    TArrayD *runs[3] = { &run, &beg, &end };
+    const double start = MTime(y, m, d).GetMjd()-40587;
+
+    vector<double> runs[3]; // { &run, &beg, &end };
+    if (!all)
+        ReadRuns(runs, fname);
 
     //check if the sqm was already installed on the telescope                                                                                                       
@@ -378,5 +598,7 @@
     PlotThresholds(start, runs, fname);
     PlotCurrent(start, runs, fname);
-    PlotRate(start, runs, fname);
+    PlotDrsTemp(start, runs, fname);
+    PlotCameraRate(start, runs, fname);
+    PlotPatchRate(start, runs, fname);
 
     gROOT->SetSelectedPad(0);
@@ -392,5 +614,5 @@
     frame1.SetStats(kFALSE);
     frame1.GetXaxis()->SetTimeDisplay(true);
-    frame1.GetXaxis()->SetTimeFormat("%H:%M %F1995-01-01 17:00:00 GMT");
+    frame1.GetXaxis()->SetTimeFormat("%H:%M %F1995-01-01 00:00:00");// 18:00:00 GMT);
     frame1.GetXaxis()->SetLabelSize(0.2);
     frame1.GetXaxis()->SetTitleSize(0.2);
@@ -400,6 +622,11 @@
 
     if (outpath)
-        c->SaveAs(outpath);
+        c->SaveAs(Form("%s/quality-%04d%02d%02d.pdf", outpath, y, m, d));
 
     return 0;
 }
+
+int quality(UInt_t y, UInt_t m, UInt_t d, const char *outpath=0, const bool all=true)
+{
+    return quality("/data/aux", y, m, d, outpath, all);
+}
