Index: trunk/Mars/fact/processing/fillratescan.C
===================================================================
--- trunk/Mars/fact/processing/fillratescan.C	(revision 15228)
+++ trunk/Mars/fact/processing/fillratescan.C	(revision 15228)
@@ -0,0 +1,432 @@
+Int_t CheckVoltage(TString fname, Double_t beg, Double_t end)
+{
+    fname.ReplaceAll("RATE_SCAN_DATA", "BIAS_CONTROL_VOLTAGE");
+
+    fits file(fname.Data());
+    if (!file)
+        return -2;
+
+    //cout << fname << endl;
+
+    Double_t time;
+    Float_t  Uout[416];
+    UShort_t Uref[416];
+    memset(Uout, 0, 416*4);
+    memset(Uref, 0, 416*2);
+
+    if (!file.SetPtrAddress("Time",  &time))
+        return -1;
+
+    if (!file.SetPtrAddress("Uout", Uout) && !file.SetPtrAddress("Uref", Uref))
+        return -1;
+
+    //cout << "Search for: " << beg-15773 << " " << end-15773 << endl;
+
+    Int_t rows = 0;
+    while (file.GetNextRow())
+    {
+        if (time<beg)
+            continue;
+
+        if (time>end)
+            break;
+
+        Int_t cnt = 0;
+        for (int i=0; i<320; i++)
+            if (Uout[i]>50 || Uref[i]>2900)
+                cnt++;
+
+        if (cnt<318)
+            return kFALSE;
+
+        rows++;
+    }
+
+    return rows>0;
+}
+
+Float_t GetOffset(TString fname, Double_t beg, Double_t end)
+{
+    fname.ReplaceAll("RATE_SCAN_DATA", "FEEDBACK_DEVIATION");
+
+    fits file(fname.Data());
+
+    //cout << fname << endl;
+
+    Double_t time;
+    Float_t  delta      = -100;
+    Float_t  delta_prev = -100;
+
+    if (!file.SetPtrAddress("Time",  &time))
+        return -100;
+
+    if (!file.SetPtrAddress("DeltaUser", &delta))
+        return -100;
+
+    //cout << "Search for: " << beg-15773 << " " << end-15773 << endl;
+
+    Int_t rows = 0;
+    while (file.GetNextRow())
+    {
+        if (time>beg)
+            return delta_prev;
+
+        delta_prev = delta;
+    }
+
+    return -100;
+}
+
+Float_t GetCurrent(TString fname, Double_t beg, Double_t end)
+{
+    fname.ReplaceAll("RATE_SCAN_DATA", "CALIBRATED_CURRENTS");
+    fname = gSystem->BaseName(fname.Data());
+
+    fname.Prepend("/scratch_nfs/calibrated_currents/");
+
+    fits file(fname.Data());
+    if (!file)
+        return -2;
+
+    //cout << fname << endl;
+
+    Double_t time;
+    Float_t med, dev;
+    if (!file.SetPtrAddress("Time",  &time) ||
+        !file.SetPtrAddress("I_med", &med))
+        return -2;
+
+    double med_avg  = 0;
+    int    cnt  = 0;
+
+    //cout << "Search for: " << beg-15773 << " " << end-15773 << endl;
+
+    while (file.GetNextRow())
+    {
+//        if (int(time)==15773)
+//            cout << time-15773 << endl;
+
+        if (time<beg)
+            continue;
+
+        if (time>end)
+            break;
+
+        med_avg += med;
+        cnt ++;
+    }
+
+    return cnt==0 ? -1 : med_avg/cnt;
+}
+
+TArrayD GetPointing(TString fname, Double_t beg, Double_t end)
+{
+    fname.ReplaceAll("RATE_SCAN_DATA", "DRIVE_CONTROL_TRACKING_POSITION");
+
+    fits file(fname.Data());
+    if (!file)
+        return TArrayD();
+
+    //cout << fname << endl;
+
+    Double_t time;
+    Double_t zd, az, ra, dec;
+    if (!file.SetPtrAddress("Time", &time) ||
+        !file.SetPtrAddress("Az",   &az)   ||
+        !file.SetPtrAddress("Zd",   &zd)   ||
+        !file.SetPtrAddress("Ra",   &ra)   ||
+        !file.SetPtrAddress("Dec",  &dec))
+        return TArrayD();
+
+    Int_t n = 0;
+
+    TArrayD rc;
+    while (file.GetNextRow())
+    {
+        if (time<beg)
+            continue;
+
+        if (time>end)
+            break;
+
+        if (rc.GetSize()==0)
+        {
+            rc.Set(6);
+
+            rc[0] = zd;
+            rc[1] = az;
+            rc[2] = zd;
+            rc[3] = az;
+
+            rc[4] = ra;
+            rc[5] = dec;
+            continue;
+        }
+
+        if (zd<rc[0]) rc[0] = zd;
+        if (zd>rc[2]) rc[2] = zd;
+
+        if (az<rc[1]) rc[1] = az;
+        if (az>rc[3]) rc[3] = az;
+
+        rc[4] += ra;
+        rc[5] += dec;
+
+        n++;
+    }
+
+    if (rc.GetSize()>0)
+    {
+        rc[4] /= n;
+        rc[5] /= n;
+    }
+
+    return rc;
+}
+
+struct data {
+    TString name;
+    int offset;
+    double time[2];
+    UShort_t th[2];
+    double rate[2];
+    int cnt;
+    Long64_t id;
+
+    data(TString fname)
+    {
+        name = fname;
+        offset = -100;
+        time[0] = time[1] = -1;
+        th[0] = th[1] = 0;
+        rate[0] = rate[1] = -1;
+        cnt = 0;
+        id = -1;
+    }
+};
+
+int Delete(MSQLMagic &serv, TString fname)
+{
+    TRegexp rex("20[0-1][0-9]/[01][0-9]/[0-3][0-9]");
+
+    TString date = fname(rex);
+
+    date.ReplaceAll("/", "-");
+
+    MTime beg;
+    beg.SetSqlDateTime(date);
+
+    TString query;
+    query += "fTimeBegin>'";
+    query += beg.GetSqlDateTime();
+    query += "' AND ";
+    query += "fTimeEnd<'";
+    query += MTime(beg.GetMjd()+1).GetSqlDateTime();
+    query += "'";
+
+    return serv.Delete("Ratescan", query) ? 1 : 2;
+}
+
+int Fill(MSQLMagic &serv, data &d)
+{
+    if (d.time[1]<0 || d.cnt==0 || d.th[0]==d.th[1])
+        return 1;
+
+    Int_t   volt    = CheckVoltage(d.name, d.time[0], d.time[1]);
+    Float_t current = GetCurrent(d.name, d.time[0], d.time[1]);
+    Float_t ov      = GetOffset(d.name, d.time[0], d.time[1]);
+    TArrayD point   = GetPointing(d.name, d.time[0], d.time[1]);
+
+    MTime tbeg(d.time[0]+d.offset);
+    MTime tend(d.time[1]+d.offset);
+
+    TString beg = tbeg.GetSqlDateTime();
+    TString end = tend.GetSqlDateTime();
+
+    cout << "=== BEG === " << beg  << '\n';
+
+    cout << " ID          " << d.id << endl;
+
+    if (current>=0)
+        cout << " CUR         " << current << '\n';
+
+    if (volt>=0)
+        cout << " VOLT        " << volt << '\n';
+
+    if (ov>-70)
+        cout << " OV          " << ov                      << '\n';
+
+    cout << " TH_beg      " << d.th[0]                  << '\n';
+    cout << " TH_end      " << d.th[1]                 << '\n';
+    cout << " RATE_beg    " << d.rate[0]                << '\n';
+    cout << " RATE_end    " << d.rate[1]               << '\n';
+    cout << " COUNT       " << d.cnt                     << '\n';
+    if (point.GetSize()>0)
+    {
+        cout << " ZD/AZ[deg]  " << point[0] << "/" << point[1] << " -- " << point[2] << "/" << point[3] <<'\n';
+        cout << " RA/DEC      " << point[4] << "h/" << point[5] << "deg\n";
+    }
+    cout << "=== END === " << MTime(d.time[1]+d.offset).GetSqlDateTime() << '\n' << endl;
+
+    TString vars;
+    if (volt>=0)
+        vars += Form("fVoltageIsOn=%d, ", volt);
+    if (current>=0)
+        vars += Form("fCurrentMedMean=%f, ", current);
+    if (ov>=-70)
+        vars += Form("fOvervoltage=%f, ", ov);
+    if (point.GetSize()>0)
+    {
+        vars += Form("fZdMin=%f, ", point[0]);
+        vars += Form("fZdMax=%f, ", point[2]);
+        vars += Form("fAzMin=%f, ", point[1]);
+        vars += Form("fAzMax=%f, ", point[3]);
+        vars += Form("fRaMean=%f, ", point[4]);
+        vars += Form("fDecMean=%f, ", point[5]);
+    }
+    vars += Form("fNight=%d, ",           MTime(tbeg.GetMjd()-1).GetNightAsInt());
+    vars += Form("fRatescanID=%d, ",      d.id);
+    vars += Form("fTimeBegin='%s', ",     beg.Data());
+    vars += Form("fTimeEnd='%s', ",       end.Data());
+    vars += Form("fRateBegin=%f, ",       d.rate[0]);
+    vars += Form("fRateEnd=%f, ",         d.rate[1]);
+    vars += Form("fThresholdBegin=%d, ",  d.th[0]);
+    vars += Form("fThresholdEnd=%d, ",    d.th[1]);
+    vars += Form("fNumPoints=%d ",       d.cnt);
+
+
+    return serv.Insert("Ratescan", vars);
+}
+
+int Process(MSQLMagic &serv, TString fname)
+{
+    data d(fname);
+
+    Int_t cnt = 0;
+
+    fits file(fname.Data());
+    if (!file)
+        return 2;
+
+    d.offset = file.GetUInt("MJDREF");
+
+    bool old = file.HasColumn("Data0");
+
+    /*  ================== That does not work, I don't know why ===================
+    Double_t  time;
+    ULong64_t id;
+    UInt_t    th;
+    Float_t   trig;
+    Float_t   ontime;
+
+    if (!file.SetPtrAddress(string("Time"), &time) ||
+        !file.SetPtrAddress(string(old ? "Data0" : "Id"), &id) ||
+        !file.SetPtrAddress(string(old ? "Data1" : "Threshold"), &th) ||
+        !file.SetPtrAddress(string(old ? "Data4" : "TriggerRate"), &trig) ||
+        !file.SetPtrAddress(string(old ? "Data3" : "RelOnTime"), &ontime))
+        return -1;
+    */
+    Double_t  *ptime   = file.SetPtrAddress("Time");
+    ULong64_t *pid     = file.SetPtrAddress(old ? "Data0" : "Id");
+    UInt_t    *pth     = file.SetPtrAddress(old ? "Data1" : "Threshold");
+    Float_t   *ptrig   = file.SetPtrAddress(old ? "Data4" : "TriggerRate");
+    Float_t   *pontime = file.SetPtrAddress(old ? "Data3" : "RelOnTime");
+
+    if (!ptime || !pid || !pth || !ptrig || !pontime)
+        return;
+
+    Double_t  &time   = *ptime;
+    ULong64_t &id     = *pid;
+    UInt_t    &th     = *pth;
+    Float_t   &trig   = *ptrig;
+    Float_t   &ontime = *pontime;
+
+    while (file.GetNextRow())
+    {
+        if (th>3000)
+            continue;
+
+        if (id!=d.id)
+        {
+            if (!Fill(serv, d))
+                return 0;
+
+            d.rate[0] = ontime>0 ? trig/ontime : -1;
+            d.time[0] = time;
+            d.th[0]   = th;
+            d.id      = id;
+
+            d.cnt = 0;
+        }
+
+        d.rate[1] = ontime>0 ? trig/ontime : -1;
+        d.time[1] = time;
+        d.th[1]   = th;
+
+        d.cnt++;
+    }
+
+    return Fill(serv, d);
+}
+
+int fillratescan(TString fname, Bool_t dummy=kTRUE)
+{
+    MSQLMagic serv("sql.rc");
+    if (!serv.IsConnected())
+    {
+        cout << "ERROR - Connection to database failed." << endl;
+        return 0;
+    }
+
+    cout << "fillratescan" << endl;
+    cout << "------------" << endl;
+    cout << endl;
+    cout << "Connected to " << serv.GetName() << endl;
+    cout << "File: " << fname << endl;
+    cout << endl;
+
+    serv.SetIsDummy(dummy);
+
+    if (!Delete(serv, fname))
+        return 1;
+
+    return Process(serv, fname);
+}
+
+int fillratescan(Bool_t dummy=kTRUE)
+{
+    MSQLMagic serv("sql.rc");
+    if (!serv.IsConnected())
+    {
+        cout << "ERROR - Connection to database failed." << endl;
+        return 0;
+    }
+
+    cout << "fillratescan" << endl;
+    cout << "------------" << endl;
+    cout << endl;
+    cout << "Connected to " << serv.GetName() << endl;
+    cout << endl;
+
+    serv.SetIsDummy(dummy);
+
+    MDirIter Next("/fact/aux", "*RATE_SCAN_DATA.fits", 3);
+
+    while (1)
+    {
+        TString name = Next();
+        if (name.IsNull())
+            break;
+
+        if (name==".")
+            continue;
+
+        cout << "File: " << name << endl;
+        if (!Delete(serv, name))
+            return 1;
+        if (!Process(serv, name))
+            return 1;
+    }
+
+    return 0;
+}
