ATLAS Offline Software
Loading...
Searching...
No Matches
DCSTxtToCool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5// DCSTxtToCool.cxx
6// Program to upload text file DCS data to COOL conditons database
7// Text files produced by Jim Cook's utility to dump from PVSS local archive
8// Richard Hawkings, started 10/1/06
9// Compiles in offline cmt framework to binary executable, needs offline env
10
11#include <utility>
12
13#include <vector>
14#include <string>
15#include <map>
16#include <fstream>
17#include <iostream>
18#include <sstream>
19
20#include "CoolKernel/DatabaseId.h"
21#include "CoolKernel/Exception.h"
22#include "CoolKernel/IDatabaseSvc.h"
23#include "CoolKernel/IDatabase.h"
24#include "CoolKernel/IFolder.h"
25#include "CoolKernel/FolderSpecification.h"
26#include "CoolKernel/IObject.h"
27#include "CoolKernel/Record.h"
28#include "CoolApplication/DatabaseSvcFactory.h"
29
30#include "DataPointInfo.h"
31#include "SealBase/Time.h"
32
34 public:
35 DCSTxtToCool(const std::string& cooldb, const std::string& configfile,
36 const std::string& datafile, const int offset);
37 int execute();
38
39 private:
40 static bool getCoolDB(const std::string& coolst, cool::IDatabasePtr& dbPtr);
41 static void readMap(const std::string& configfile);
42 void beginDataPoint(const std::string& folder);
43 void storeDataPoint(cool::ValidityKey since, float value);
44 void flushBuffer();
45 static cool::IFolderPtr getFolder(const std::string& folder,
46 const cool::IRecordSpecification& atrspec);
47
48 std::string m_coolstr;
49 std::string m_configfile;
50 std::string m_datafile;
52
53 cool::IDatabasePtr m_coolDb;
55 std::string m_datap;
56 cool::IFolderPtr m_folderp;
58 cool::ValidityKey m_vkmin;
59 cool::ValidityKey m_vkmax;
60 typedef std::map<std::string, DataPointInfo*> DPMap;
62 std::vector<std::string> m_folderlist{};
63 std::vector<int> m_folderchan{};
64};
65
66DCSTxtToCool::DCSTxtToCool(const std::string& cooldb,
67 const std::string& configfile, const std::string& datafile, const int offset) :
68 m_coolstr(cooldb), m_configfile(configfile), m_datafile(datafile),
69 m_timeoffset(offset),
70 m_ndata(0), m_datap(""), m_vkmin(cool::ValidityKeyMax), m_vkmax(0) {
71 std::cout << "Read data into COOL db: " << m_coolstr << std::endl;
72 std::cout << "Datapoint configuration file: " << m_configfile << std::endl;
73 std::cout << "Data file: " << m_datafile << std::endl;
74 std::cout << "Time offset " << m_timeoffset << " hours" << std::endl;
75}
76
78 // open COOL database
80 std::cout << "COOL database opened" << std::endl;
81 } else {
82 std::cout << "Database open fails" << std::endl;
83 return 1;
84 }
85 // read datapoint mapping
87 // loop over input lines
88 std::ifstream infile;
89 int nobj=0;
90 std::vector<char> buffer(999);
91 infile.open(m_datafile.c_str());
92 while (infile.getline(&buffer[0],999,'\n')) {
93 std::string sline(buffer.begin(),buffer.begin()+strlen(&buffer[0]));
94 // parse line with assumptions
95 // if string begins with '200' (e.g. 2006) assume date, hence datapoint
96 if (sline.substr(0,3)=="200") {
97 // parse the string as three fields - date, time, value (float)
98 std::string sdate,stime;
99 float value;
100 std::istringstream sbuf(&buffer[0]);
101 sbuf >> sdate >> stime >> value;
102 int year,month,day,hour,min,sec;
103 long long frac;
104 year=atoi(sdate.substr(0,4).c_str());
105 // note -1 as month is returned by timefunctions in range 0-11
106 month=atoi(sdate.substr(5,2).c_str())-1;
107 day=atoi(sdate.substr(8,2).c_str());
108 hour=atoi(stime.substr(0,2).c_str());
109 min=atoi(stime.substr(3,2).c_str());
110 sec=atoi(stime.substr(6,2).c_str());
111 frac=atoi(stime.substr(9,3).c_str())*1E6;
112 seal::Time sincet=seal::Time(year,month,day,
113 hour,min,sec,frac,false);
114 seal::TimeSpan tofs=seal::TimeSpan(3600*m_timeoffset,0);
115 sincet=sincet+tofs;
116 storeDataPoint(sincet.ns(),value);
117 } else if (sline.size()>2) {
118 // if size >2 assume a new datapoint with this name
119 beginDataPoint(sline);
120 }
121 ++nobj;
122 }
123 // write last data
124 if (m_ndata>0) flushBuffer();
125 std::cout << "Read total of " << nobj << " lines from data file" << std::endl;
126 return 0;
127}
128
129void DCSTxtToCool::beginDataPoint(const std::string& datap) {
130 if (m_ndata>0) flushBuffer();
131 // strip trailing linefeeds
132 while (datap.substr(datap.size()-1,1)=="\r")
133 datap.pop_back();
134 // lookup datapoint to folder mapping
135 std::cout << "Begin processing datapoint " << datap << std::endl;
136 std::string key0=m_dpmap.begin()->first;
137 DPMap::const_iterator fitr=m_dpmap.find(datap);
138 if (fitr!=m_dpmap.end()) {
139 m_dpinfo=fitr->second;
140 m_datap=std::move(datap);
141 std::cout << "Associated datapoint to folder " << m_dpinfo->folder() <<
142 " channel " << m_dpinfo->channel() << std::endl;
143 // now get pointer to COOL folder, creating if needed
144 try {
145 m_folderp=getFolder(m_dpinfo->folder(),m_dpinfo->atrspec());
146 }
147 catch (std::exception& e) {
148 // if folder creation fails, don't let data be stored
149 std::cout << "No valid folder to store data: " << e.what()
150 << std::endl;
151 m_dpinfo=nullptr;
152 }
153 } else {
154 std::cout << "ERROR: No mapping defined for datapoint " << datap <<
155 std::endl;
156 m_dpinfo=nullptr;
157 }
158}
159
160void DCSTxtToCool::storeDataPoint(cool::ValidityKey since, float value) {
161 // if no valid folder mapping defined, skip storage
162 if (m_dpinfo==nullptr) return;
163 if (m_ndata==0) m_folderp->setupStorageBuffer();
164 cool::Record payload(m_dpinfo->atrspec());
165 payload[m_dpinfo->column()].setValue(value);
166 m_folderp->
167 storeObject(since,cool::ValidityKeyMax,payload,m_dpinfo->channel());
168 ++m_ndata;
169 // keep track of min/max times for printout
170 if (since<m_vkmin) m_vkmin=since;
171 if (since>m_vkmax) m_vkmax=since;
172}
173
175 // if no data, nothing to do
176 if (m_ndata==0) return;
177 if (m_datap=="") {
178 std::cout << "Attempt to write " << m_ndata << " data points but no folder"
179 << std::endl;
180 return;
181 }
182 std::cout << "Write " << m_ndata << " values [" <<
183 seal::Time(m_vkmin).format(false,"%c") << ", " <<
184 seal::Time(m_vkmax).format(false,"%c") << "] from datapoint "
185 << m_datap << " to folder " << m_dpinfo->folder() << " channel "
186 << m_dpinfo->channel() << std::endl;
187 try {
188 m_folderp->flushStorageBuffer();
189 }
190 catch (std::exception& e ) {
191 std::cout << "Bulk insertion failed for folder " <<
192 m_dpinfo->folder() << " channel " << m_dpinfo->channel() <<
193 ", reason: " << e.what() << std::endl;
194 }
195 m_ndata=0;
196 m_vkmin=cool::ValidityKeyMax;
197 m_vkmax=0;
198}
199
200
201bool DCSTxtToCool::getCoolDB(const std::string& coolstr,
202 cool::IDatabasePtr& dbPtr) {
203 std::cout << "Attempt to open COOL database with connection string: "
204 << coolstr << std::endl;
205 cool::IDatabaseSvc& dbSvc=cool::DatabaseSvcFactory::databaseService();
206 try {
207 dbPtr=dbSvc.openDatabase(coolstr,false);
208 return true;
209 }
210 catch (std::exception& e) {
211 std::cout << "COOL exception caught: " << e.what() << std::endl;
212 std::cout << "Try to create new conditions DB" << std::endl;
213 try {
214 dbPtr=dbSvc.createDatabase(coolstr);
215 std::cout << "Creation succeeded" << std::endl;
216 return true;
217 }
218 catch (std::exception& e) {
219 std::cout << "Creation failed" << std::endl;
220 return false;
221 }
222 }
223 return false;
224}
225
226void DCSTxtToCool::readMap(const std::string& configfile) {
227 std::cout << "Read configuration from file: " << configfile << std::endl;
228 m_dpmap.clear();
229 m_folderlist.clear();
230 m_folderchan.clear();
231 std::ifstream infile;
232 infile.open(configfile.c_str());
233 std::string dpname, folder, column;
234 int channel;
235 int nobj=0;
236 while (infile >> dpname >> folder >> column >> channel) {
237 ++nobj;
238 cool::RecordSpecification atrspec;
239 atrspec.extend(column,cool::StorageType::Float);
240 DataPointInfo* dptr=new DataPointInfo(folder,column,channel,atrspec);
241 m_dpmap.insert(std::pair<std::string,DataPointInfo*>(dpname,dptr));
242
243 // check if this folder exists already in list
244 bool found=false;
245 for (unsigned int i=0;i<m_folderlist.size();++i) {
246 if (m_folderlist[i]==folder) {
247 ++m_folderchan[i];
248 found=true;
249 }
250 }
251 if (!found) {
252 m_folderlist.push_back(folder);
253 m_folderchan.push_back(1);
254 }
255 } // end input loop
256 std::cout << "Read " << nobj << " lines from file, giving " <<
257 m_dpmap.size() << " datapoint mappings " << std::endl;
258 std::cout << "Total of " << m_folderlist.size() << " COOL folders used" <<
259 std::endl;
260 for (unsigned int i=0;i<m_folderlist.size();++i)
261 std::cout << "Folder " << m_folderlist[i] << " channel count " <<
262 m_folderchan[i] << std::endl;
263}
264
265cool::IFolderPtr DCSTxtToCool::getFolder(const std::string& folder,
266 const cool::IRecordSpecification& atrspec) {
267 if (m_coolDb->existsFolder(folder)) {
268 std::cout << "Folder " << folder << " already exists in database"
269 << std::endl;
270 return m_coolDb->getFolder(folder);
271 } else {
272 std::cout << "Folder " << folder << " not found - try to create it" <<
273 std::endl;
274 // create folder (single version), and create parents if needed
275 // description string is used to signal data type to Athena
276 // depends if folder is single or multichannel
277 int nchan=0;
278 for (unsigned int i=0;i<m_folderlist.size();++i)
279 if (m_folderlist[i]==folder) nchan=m_folderchan[i];
280 std::string desc="dummy";
281 if (nchan==1) desc="<timeStamp>time</timeStamp><addrHeader><address_header service_type=\"71\" clid=\"40774348\" /></addrHeader><typeName>AthenaAttributeList</typeName>";
282 if (nchan>1) desc="<timeStamp>time</timeStamp><addrHeader><address_header service_type=\"71\" clid=\"1238547719\" /></addrHeader><typeName>CondAttrListCollection</typeName>";
283 std::cout << "Folder description string set to: " << desc << std::endl;
284 cool::IFolderPtr folderptr=m_coolDb->createFolder(folder,cool::FolderSpecification(cool::FolderVersioning::SINGLE_VERSION,atrspec),desc,true);
285 return folderptr;
286 }
287}
288
289int main(int argc, const char* argv[]) {
290 if (argc<4) {
291 std::cout << "Syntax: DCSTxtToCool,exe <coolDBconnection> <configfile> <datafile> {<offset>}" << std::endl;
292 return 1;
293 }
294 std::string coolstr=argv[1];
295 std::string configfile=argv[2];
296 std::string datafile=argv[3];
297 int offset=0;
298 if (argc>4) offset=atoi(argv[4]);
299 DCSTxtToCool convert(coolstr,configfile,datafile,offset);
300 return convert.execute();
301}
302
#define min(a, b)
Definition cfImp.cxx:40
DataPointInfo * m_dpinfo
cool::IDatabasePtr m_coolDb
std::vector< std::string > m_folderlist
cool::IFolderPtr m_folderp
std::map< std::string, DataPointInfo * > DPMap
std::string m_datap
std::string m_coolstr
static void readMap(const std::string &configfile)
std::string m_configfile
cool::ValidityKey m_vkmax
static bool getCoolDB(const std::string &coolst, cool::IDatabasePtr &dbPtr)
std::vector< int > m_folderchan
static cool::IFolderPtr getFolder(const std::string &folder, const cool::IRecordSpecification &atrspec)
cool::ValidityKey m_vkmin
DCSTxtToCool(const std::string &cooldb, const std::string &configfile, const std::string &datafile, const int offset)
void beginDataPoint(const std::string &folder)
void storeDataPoint(cool::ValidityKey since, float value)
std::string m_datafile
std::string stime()
return the current data and time
int main()
Definition hello.cxx:18