/* ======================================================================== *\ ! ! * ! * 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): Daniela Dorner, 08/2004 ! Author(s): Thomas Bretz, 08/2004 ! ! Copyright: MAGIC Software Development, 2000-2004 ! ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // filldotrun.C // ============ // // This macro is used in the datacenter to automatically fill the run-database // with the information stored in the .run-files written by the central // control. // // To following Arehucas versions are Currently supported: // 040505-0, 040514-0, // 040518-0, 040727-0, // 041113-0, 041209-0, 041221-0 // 050224-0, 050317-0, 050322-0, 050401-0, 050413-0, 050415-0 // // Usage: // .x filldotrun.C+("/data/MAGIC/Period019/ccdata", kTRUE) // // While the first argument is the directory in which all subdirectories where // searches for CC_*.run files. All these files were analysed and the run // info will be put into the DB, eg: // "/data/MAGIC" would do it for all data // "/data/MAGIC/Period019/ccdata" would do it for one Period // "/data/MAGIC/Period019/ccdata/2004_05_17" would do it for a single day // "/data/MAGIC/Period019/ccdata/file.run" would do it for a single file // // The second argument is the 'dummy-mode'. If it is kTRUE dummy-mode is // switched on and nothing will be written into the database. Instead // informations about the subtables are displayed. This is usefull for tests // when adding a new arehucas version support. If it is kFALSE the information // are written into the subtables and the runs info is written into the // rundatabase. // // In the automatic case it makes sense to check the logfiles to make sure // that everything is fine... // // Make sure, that database and password are corretly set in a resource // file called sql.rc and the resource file is found. // // Remark: Running it from the commandline looks like this: // root -q -l -b filldotrun.C+\(\"path\"\,kFALSE\) 2>&1 | tee filldotrun.log // // Returns 0 in case of failure and 1 in case of success. // ///////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include "MTime.h" #include "MDirIter.h" #include "MSQLServer.h" using namespace std; Bool_t ExistStr(MSQLServer &serv, const char *column, const char *table, const char *test) { TString query(Form("SELECT %s FROM %s WHERE %s='%s'", column, table, column, test)); TSQLResult *res = serv.Query(query); if (!res) return kFALSE; Bool_t rc = kFALSE; TSQLRow *row=res->Next(); if (row && (*row)[0]) rc=kTRUE; delete res; return rc; } Int_t QueryNameKEY(MSQLServer &serv, Bool_t dummy, const char *col, const char *name, Bool_t insert=kTRUE) { TString query; query = Form("SELECT f%sKEY FROM %s WHERE f%sName='%s'", col, col, col, name); TSQLResult *res = serv.Query(query); if (!res) return -1; TSQLRow *row=res->Next(); Int_t rc = row && (*row)[0] ? atoi((*row)[0]) : -1; delete res; if (rc>=0) return rc; if (!insert) return -1; query = Form("INSERT %s (f%sName) VALUES (\"%s\");", col, col, name); if (dummy) { cout << query << endl; return 0; } res=serv.Query(query); if (!res) return -1; delete res; Int_t key = QueryNameKEY(serv, dummy, col, name, kFALSE); if (key>0) { cout << "New " << col << ": " << name << endl; return key; } cout << "ERROR: " << query << endl; return kFALSE; } Int_t insert(MSQLServer &serv, Bool_t dummy, TString filename) { ifstream fin(filename); if (!fin) { cout << "Could not open file " << filename << endl; return -1; } TString strng; strng.ReadLine(fin); if (strng!=TString("[CC Plain Run Summary File]")) { cout << filename << ": No Plain Run Summary File" << endl; cout << "First Line: " << strng << endl; cout << endl; return -1; } strng.ReadLine(fin); TRegexp reg("[0-9][0-9][0-9][0-9][0-9][0-9]-[0-9]"); TString arehucas = strng(reg); arehucas.Prepend("20"); arehucas.ReplaceAll("-", ""); Int_t version = atoi(arehucas.Data()); if (version!=200405050 && version!=200405140 && version!=200405180 && version!=200407270 && version!=200411130 && version!=200412090 && version!=200412210 && version!=200502240 && version!=200503170 && version!=200503220 && version!=200504010 && version!=200504130 && version!=200504150) { cout << filename << ": File Version unknown - please update the macro!" << endl; cout << "Second Line: " << strng << endl; cout << endl; return -1; } cout << " V" << version << " " << flush; Int_t cnt=0; while (1) { // ========== Col 1: Run Number ========= //Reading the line //and converting some strings to ints/floats strng.ReadToDelim(fin, ' '); if (!fin) break; Int_t runnumber = atoi(strng.Data()); //runnumber=0 means no valid dataset //-> continue if (runnumber == 0) { strng.ReadLine(fin); cout << "Runnumber == 0" << endl; continue; } //cout << "RunNo: " << runnumber << " "; if (ExistStr(serv, "fRunNumber", "RunData", strng.Data())) { // FIXME: Maybe we can implement an switch to update mode? cout << "Run #" << runnumber << " already existing... skipped." << endl; strng.ReadLine(fin); continue; } // ========== Col 2: Run Type ========= strng.ReadToDelim(fin, ' '); if (strng.Contains("???")) strng="n/a"; Int_t runtype = QueryNameKEY(serv, dummy, "RunType", strng.Data(), kFALSE); if (runtype<0) { cout << "ERROR - RunType " << strng << " not available." << endl; strng.ReadLine(fin); continue; } //cout << runtype << " "; // ========== Col 3,4: Start Time ========= TString startdate, starttime; startdate.ReadToDelim(fin, ' '); starttime.ReadToDelim(fin, ' '); //cout << startdate << " " << starttime << " "; // ========== Col 5,6: Stop Time ========= TString stopdate, stoptime; stopdate.ReadToDelim(fin, ' '); stoptime.ReadToDelim(fin, ' '); //cout << stopdate << " " << stoptime << " "; if (startdate.Contains("???")) startdate="0000-00-00"; if (starttime.Contains("???")) starttime="00:00:00"; if (stopdate.Contains("???")) stopdate="0000-00-00"; if (stoptime.Contains("???")) stoptime="00:00:00"; // ========== Col 7: Source Name ========= strng.ReadToDelim(fin, ' '); if (strng.Contains("???")) strng="Unavailable"; Int_t sourcekey = QueryNameKEY(serv, dummy, "Source", strng.Data()); if (sourcekey<0) { strng.ReadLine(fin); continue; } //cout << sourcekey << " "; // ========== Col 8,9: Local source position ========= strng.ReadToDelim(fin, ' '); Float_t zd = atof(strng.Data()); strng.ReadToDelim(fin, ' '); Float_t az = atof(strng.Data()); //cout << zd << " " << az << " "; // ========== Col 10: Number of Events ========= strng.ReadToDelim(fin, ' '); Int_t evtno = atoi(strng.Data()); //cout << evtno << " "; // ========== Col 11: Project Name ========= strng.ReadToDelim(fin, ' '); if (strng.Contains("???")) strng="Unavailable"; Int_t projkey = QueryNameKEY(serv, dummy, "Project", strng.Data()); if (projkey<0) { strng.ReadLine(fin); continue; } //cout << projkey << " "; // ========== Col 12: Trigger Table Name ========= // starting from version 200411130: Col 12,13: Trigger Table Name ========= strng.ReadToDelim(fin, ' '); if (strng.Contains("???")) strng="n/a"; Int_t l1triggerkey=1; Int_t l2triggerkey=1; if (version >=200411130) { l1triggerkey = QueryNameKEY(serv, dummy, "L1TriggerTable", strng.Data()); if (l1triggerkey<0) { strng.ReadLine(fin); continue; } strng.ReadToDelim(fin, ' '); if (strng.Contains("???")) strng="n/a"; l2triggerkey = QueryNameKEY(serv, dummy, "L2TriggerTable", strng.Data()); if (l2triggerkey<0) { strng.ReadLine(fin); continue; } } else { Int_t c=0; if (strng.Contains(":")) c=1; if (strng.Contains("L1_") && !(strng.Contains(":"))) c=2; if (strng.Contains("n/a")) c=3; switch (c) { case 0: { l2triggerkey = QueryNameKEY(serv, dummy, "L2TriggerTable", strng.Data()); if (l2triggerkey<0) { strng.ReadLine(fin); continue; } strng="n/a"; l1triggerkey = 1; break; } case 1: { TString L1TT, L2TT; L2TT=strng(7,12); L1TT=strng(0,6); l1triggerkey = QueryNameKEY(serv, dummy, "L1TriggerTable", L1TT.Data()); if (l1triggerkey<0) { strng.ReadLine(fin); continue; } l2triggerkey = QueryNameKEY(serv, dummy, "L2TriggerTable", L2TT.Data()); if (l2triggerkey<0) { strng.ReadLine(fin); continue; } break; } case 2: { l1triggerkey = QueryNameKEY(serv, dummy, "L1TriggerTable", strng.Data()); if (l1triggerkey<0) { strng.ReadLine(fin); continue; } strng="n/a"; l2triggerkey = 1; break; } case 3: { l1triggerkey = 1; l2triggerkey = 1; break; } default: { cout << "WARNING: neiter L1 nor L2 Trigger table - please check what is happening." << strng << endl; break; } } } // ========== Col 13-15: TrigRate, L2 UnPresc Rate, L2 Presc Rate ========== strng.ReadToDelim(fin, ' '); Float_t trigrate = atof(strng.Data()); strng.ReadToDelim(fin, ' '); Float_t l2uprate = atof(strng.Data()); strng.ReadToDelim(fin, ' '); Float_t l2prrate = atof(strng.Data()); // ========== Col 16,17: DaqRate, Storage Rate ========== strng.ReadToDelim(fin, ' '); Float_t daqrate = atof(strng.Data()); strng.ReadToDelim(fin, ' '); Float_t storerate = atof(strng.Data()); // ========== Col 18: HV table ========= if (version==200405050 || version==200405140) strng.ReadToDelim(fin, '\n'); else strng.ReadToDelim(fin, ' '); if (strng.Contains("???")) strng="n/a"; Int_t hvkey = QueryNameKEY(serv, dummy, "HvSettings", strng.Data()); if (hvkey<0) { //strng.ReadLine(fin); continue; } if (version==200405180 || version==200407270) strng.ReadLine(fin); Int_t testflagkey=1; Int_t lightcondkey=1; Int_t dttablekey=1; Int_t triggerdelaytablekey=1; Int_t calibrationscriptkey=1; if (version==200411130 || version==200412090 || version==200412210 || version==200502240 || version==200503170 || version==200503220 || version==200504010 || version==200504130 || version==200504150) { // ========== Col 19-35: DC and HV-values, mjd ========= for (int i=0 ; i<17 ; i++) { strng.ReadToDelim(fin, ' '); } // ========== Col 36: test-flag ========= strng.ReadToDelim(fin, ' '); if (strng.Contains("???")) strng="n/a"; testflagkey = QueryNameKEY(serv, dummy, "TestFlag", strng.Data()); if (testflagkey<0) { strng.ReadLine(fin); continue; } // ========== Col 37: light conditions ========= strng.ReadToDelim(fin, ' '); if (strng.Contains("???")) strng="n/a"; lightcondkey = QueryNameKEY(serv, dummy, "LightConditions", strng.Data()); if (lightcondkey<0) { strng.ReadLine(fin); continue; } // ========== Col 38: discriminator threshold table ========= strng.ReadToDelim(fin, ' '); if (strng.Contains("???")) strng="n/a"; dttablekey = QueryNameKEY(serv, dummy, "DiscriminatorThresholdTable", strng.Data()); if (dttablekey<0) { strng.ReadLine(fin); continue; } // ========== Col 39: trigger delay table ========= strng.ReadToDelim(fin, ' '); if (strng.Contains("???")) strng="n/a"; triggerdelaytablekey = QueryNameKEY(serv, dummy, "TriggerDelayTable", strng.Data()); if (triggerdelaytablekey<0) { strng.ReadLine(fin); continue; } // ========== Col 40,41: RA and Dec sent to drive ========= strng.ReadToDelim(fin, ' '); strng.ReadToDelim(fin, ' '); // ========== Col 42: Calibration Script ========= strng.ReadToDelim(fin, '\n'); if (strng.Contains("???")) strng="n/a"; calibrationscriptkey = QueryNameKEY(serv, dummy, "CalibrationScript", strng.Data()); if (calibrationscriptkey<0) { strng.ReadLine(fin); continue; } } // ================================================================ // ========== Data read from file now access the database ========= // ================================================================ //assemlbe the query that is needed to insert the values of this run TString query; query += "INSERT RunData SET "; query += Form("fRunNumber=%d, ", runnumber); query += Form("fRunTypeKEY=%d, ", runtype); query += Form("fProjectKEY=%d, ", projkey); query += Form("fSourceKEY=%d, ", sourcekey); query += Form("fNumEvents=%d, ", evtno); query += Form("fRunStart=\"%s %s\", ", startdate.Data(), starttime.Data()); query += Form("fRunStop=\"%s %s\", ", stopdate.Data(), stoptime.Data()); query += Form("fL1TriggerTableKEY=%d, ", l1triggerkey); query += Form("fL2TriggerTableKEY=%d, ", l2triggerkey); query += Form("fTestFlagKEY=%d, ", testflagkey); query += Form("fCalibrationScriptKEY=%d, ", calibrationscriptkey); query += Form("fTriggerDelayTableKEY=%d, ", triggerdelaytablekey); query += Form("fDiscriminatorThresholdTableKEY=%d, ", dttablekey); query += Form("fLightConditionsKEY=%d, ", lightcondkey); query += Form("fHvSettingsKEY=%d, ", hvkey); if (!TMath::IsNaN(zd) && TMath::Finite(zd)) query += Form("fZenithDistance=%d, ", TMath::Nint(zd)); if (!TMath::IsNaN(az) && TMath::Finite(az)) query += Form("fAzimuth=%d, ", TMath::Nint(az)); if (!TMath::IsNaN(storerate) && TMath::Finite(storerate)) query += Form("fDaqStoreRate=%d, ", TMath::Nint(storerate)); if (!TMath::IsNaN(daqrate) && TMath::Finite(daqrate)) query += Form("fDaqTriggerRate=%d, ", TMath::Nint(daqrate)); if (!TMath::IsNaN(trigrate) && TMath::Finite(trigrate)) query += Form("fMeanTriggerRate=%d, ", TMath::Nint(trigrate)); if (!TMath::IsNaN(l2prrate) && TMath::Finite(l2prrate)) query += Form("fL2RatePresc=%d, ", TMath::Nint(l2prrate)); if (!TMath::IsNaN(l2uprate) && TMath::Finite(l2uprate)) query += Form("fL2RateUnpresc=%d, ", TMath::Nint(l2uprate)); query += "fMagicNumberKEY=1, fExcludedFDAKEY=1"; cnt++; if (dummy) continue; //send query, add dataset to DB TSQLResult *res = serv.Query(query); if (!res) return -1; delete res; //create entry in table RunProcessStatus for this runnumber TString query2=Form("INSERT RunProcessStatus SET fRunNumber=%d, fTimingCorrection='1970-01-01 00:00:00'", runnumber); res = serv.Query(query2); if (!res) return -1; delete res; } return cnt; } // This tool will work from Period017 (2004_05_17) on... int filldotrun(const TString path="/data/MAGIC/Period018/ccdata", Bool_t dummy=kTRUE) { TEnv env("sql.rc"); MSQLServer serv(env); if (!serv.IsConnected()) { cout << "ERROR - Connection to database failed." << endl; return 0; } cout << "filldotrun" << endl; cout << "----------" << endl; cout << endl; cout << "Connected to " << serv.GetName() << endl; cout << "Search Path: " << path << endl; cout << endl; if (path.EndsWith(".run")) { cout << path(TRegexp("CC_.*.run", kFALSE)) << flush; Int_t n = insert(serv, dummy, path); cout << " <" << n << "> " << (dummy?"DUMMY":"") << endl; return n<0 ? 0 : 1; } MDirIter Next(path, "CC_*.run", -1); while (1) { TString name = Next(); if (name.IsNull()) break; cout << name(TRegexp("CC_.*.run", kFALSE)) << flush; Int_t n = insert(serv, dummy, name); cout << " <" << n << "> " << (dummy?"DUMMY":"") << endl; if (n<0) return 0; } return 1; }