CGEM BOSS 6.6.5.f
BESIII Offline Software System
Loading...
Searching...
No Matches
CgemCalibFunSvc.cxx
Go to the documentation of this file.
1#include "CgemCalibFunSvc/CgemCalibFunSvc.h"
2#include "GaudiKernel/Kernel.h"
3#include "GaudiKernel/IInterface.h"
4#include "GaudiKernel/StatusCode.h"
5#include "GaudiKernel/SvcFactory.h"
6#include "GaudiKernel/MsgStream.h"
7
8#include "GaudiKernel/IIncidentSvc.h"
9#include "GaudiKernel/Incident.h"
10#include "GaudiKernel/IIncidentListener.h"
11
12#include "GaudiKernel/ISvcLocator.h"
13#include "GaudiKernel/Bootstrap.h"
14
15#include "GaudiKernel/IDataProviderSvc.h"
16#include "GaudiKernel/SmartDataPtr.h"
17#include "GaudiKernel/DataSvc.h"
18#include "GaudiKernel/IJobOptionsSvc.h"
19
20#include "CalibData/CalibModel.h"
21// #include "CalibData/Cgem/CgemCalibData.h"
22// #include "CalibData/Cgem/CgemDataConst.h"
23#include "EventModel/EventHeader.h"
24#include "GaudiKernel/SmartDataPtr.h"
25
26#include <iomanip>
27#include <iostream>
28#include <fstream>
29#include <cmath>
30#include <cstring>
31
32#include "TFile.h"
33#include "TTree.h"
34
35using namespace std;
36
37CgemCalibFunSvc::CgemCalibFunSvc( const string& name, ISvcLocator* svcloc) :Service (name, svcloc){
38 declareProperty("PrintInfo", m_printInfo=false);
39 declareProperty("TimeFitFile", m_timeFitFile);
40 declareProperty("TimeFitFilePath", m_timeFitFilePath);
41 declareProperty("TimeWalkCalibFile", m_timeWalkFileName);
42 declareProperty("LUTFile", m_fileLUT);
43}
44
46}
47
48StatusCode CgemCalibFunSvc::queryInterface(const InterfaceID& riid, void** ppvInterface){
49 if( IID_ICgemCalibFunSvc.versionMatch(riid) ){
50 *ppvInterface = static_cast<ICgemCalibFunSvc*> (this);
51 } else{
52 return Service::queryInterface(riid, ppvInterface);
53 }
54 return StatusCode::SUCCESS;
55}
56
58 MsgStream log(messageService(), name());
59 log << MSG::INFO << "CgemCalibFunSvc::initialize()" << endreq;
60
61 StatusCode sc = Service::initialize();
62 if( sc.isFailure() ) return sc;
63
64 // IIncidentSvc* incsvc;
65 // sc = service("IncidentSvc", incsvc);
66 // int priority = 100;
67 // if( sc.isSuccess() ){
68 // incsvc -> addListener(this, "NewRun", priority);
69 // }
70
71 m_getRunNo = false;
72 static IJobOptionsSvc* jobSvc = 0;
73 if ( jobSvc == 0 ) {
74 sc = service("JobOptionsSvc", jobSvc);
75 if ( sc.isFailure() ) {
76 std::cout << "Can't get the JobOptionsSvc @ DistBoss::GetPropertyValue()" << std::endl;
77 return sc;
78 }
79 }
80 const vector<const Property*>* properties = jobSvc->getProperties("ReadCosmicRayData");
81 if ( properties == NULL ) {
82 log << MSG::WARNING << "can not get runNo from ReadCosmicRayData" << endreq;
83 } else{
84 for ( unsigned int i = 0; i < properties->size(); ++i ) {
85 if ( properties->at(i)->name() == "runNo" ) {
86 cout << "name of property: " << properties->at(i)->name() << endl;
87 string strRnd = properties->at(i)->toString();
88 sscanf(strRnd.c_str(), "%d", &m_run);
89 // cout << "runNo: " << m_run << endl;
90 break;
91 }
92 }
93 m_getRunNo = true;
94 }
95 if( !initCalibConst() ){
96 log << MSG::ERROR << "can not initialize CGEM calibration constants" << endreq;
97 return StatusCode::FAILURE;
98 }
99
100 sc = service("CalibDataSvc", m_pCalDataSvc, true);
101 if( sc == StatusCode::SUCCESS ){
102 log << MSG::INFO << "Retrieve IDataProviderSvc" << endreq;
103 }else{
104 log << MSG::FATAL << "can not get IDataProviderSvc" << endreq;
105 }
106
107 m_readLUT = true;
108 m_cgemLUTReader = new CgemLUTReader(m_fileLUT.c_str());
109 cout << "LUT file: " << m_fileLUT << endl;
110 if(!m_cgemLUTReader->ReadLUT()){
111 m_readLUT = false;
112 log << MSG::FATAL << "can not read LUT " << m_fileLUT << endl;
113 }
114
115 return StatusCode::SUCCESS;
116}
117
119 MsgStream log(messageService(), name());
120 log << MSG::INFO << "CgemCalibFunSvc::finalize()" << endreq;
121
122 return StatusCode::SUCCESS;
123}
124
125void CgemCalibFunSvc::handle(const Incident& inc){
126 MsgStream log( messageService(), name() );
127 log << MSG::DEBUG << "handle: " << inc.type() << endreq;
128
129 if ( inc.type() == "NewRun" ){
130 log << MSG::DEBUG << "NewRun" << endreq;
131
132 if( ! initCalibConst() ){
133 log << MSG::ERROR
134 << "can not initilize Cgem Calib Constants" << endl
135 << " Please insert the following statement "
136 << "in your \"jobOption.txt\" "
137 << "before the include file of Cgem Reconstruction: "
138 << endl << " "
139 << "#include \"$CALIBSVCROOT/share/job-CalibData.txt\""
140 << endreq;
141 }
142 }
143}
144
145bool CgemCalibFunSvc::initCalibConst(){
146 MsgStream log(messageService(), name());
147 log << MSG::INFO << "read calib const from TCDS" << endreq;
148
149 // IDataProviderSvc* eventSvc = NULL;
150 // Gaudi::svcLocator()->service("EventDataSvc", eventSvc);
151 // SmartDataPtr<Event::EventHeader> eventHeader(eventSvc,"/Event/EventHeader");
152 // if (!eventHeader) {
153 // log << MSG::FATAL << "Could not find Event Header" << endreq;
154 // return( StatusCode::FAILURE);
155 // }
156 // m_run = eventHeader->runNumber();
157
158 // clear calibconst
159
160 // string fullPath = "/Calib/CgemCal";
161 // SmartDataPtr<CalibData::CgemCalibData> calConst(m_pCalDataSvc, fullPath);
162 // if( ! calConst ){
163 // log << MSG::ERROR << "can not get CgemCalibConst via SmartPtr"
164 // << endreq;
165 // return false;
166 // }
167
168 char fname[500];
169 if(!m_timeFitFile.empty()){
170 sprintf(fname, "%s", m_timeFitFile.c_str());
171 } else if(m_getRunNo && m_timeFitFile.empty()){
172 sprintf(fname, "%s/timeFit_Run%d.txt", m_timeFitFilePath.c_str(), m_run);
173 } else{
174 cout << "ERROR: can not get runNo and CGEM calibration file" << endl;
175 return false;
176 }
177
178 cout << "Open CGEM calibration file: " << fname << endl;
179 ifstream fconst(fname);
180 if(!fconst){
181 log << MSG::ERROR << "can not find calibration constants. Please check runNo or calibration file" << endreq;
182 return false;
183 }
184
185 string str;
186 getline(fconst, str);
187 for(int layer=0; layer<NLAYER; layer++){
188 if(0==layer){
189 for(int i=0; i<5; i++) fconst >> str;
190 for(int xv=0; xv<NXV; xv++){
191 fconst >> str >> m_tRising[layer][xv][0] >> m_tFalling[layer][xv][0];
192 m_tRising[layer][xv][1] = m_tRising[layer][xv][0];
193 m_tFalling[layer][xv][1] = m_tFalling[layer][xv][0];
194 }
195 } else{
196 for(int i=0; i<7; i++) fconst >> str;
197 for(int xv=0; xv<NXV; xv++){
198 fconst >> str >> m_tRising[layer][xv][0] >> m_tFalling[layer][xv][0]
199 >> m_tRising[layer][xv][1] >> m_tFalling[layer][xv][1];
200 }
201 }
202 }
203 fconst.close();
204
205 if(m_printInfo){
206 cout << "print CGEM time fit calibration constants" << endl;
207 for(int layer=0; layer<NLAYER; layer++){
208 cout << "layer " << layer << endl;
209 for(int xv=0; xv<NXV; xv++){
210 for(int sheet=0; sheet<NSHEET; sheet++){
211 if((0==layer) && (1==sheet)) continue;
212 cout << setw(15) << m_tRising[layer][xv][sheet] << setw(15) << m_tFalling[layer][xv][sheet];
213 }
214 }
215 cout << endl;
216 }
217 }
218
219 // read time walk calibration constants
220 Float_t tw, charge, threshold;
221 TFile ftw(m_timeWalkFileName.c_str());
222 cout << "time walk file: " << m_timeWalkFileName << endl;
223 TTree* trTw = (TTree*)ftw.Get("tree");
224 trTw->SetBranchAddress("time_correction", &tw);
225 trTw->SetBranchAddress("charge", &charge);
226 trTw->SetBranchAddress("threshold", &threshold);
227 int nEntries = trTw->GetEntries();
228 for(int i=0; i<nEntries; i++){
229 trTw->GetEntry(i);
230 m_tw.push_back((double)tw);
231 m_charge.push_back((double)charge);
232 m_threshold.push_back((double)threshold);
233
234 if(0==i){
235 m_valThreshold.push_back(threshold);
236 m_thIdFrom.push_back(i);
237 } else{
238 bool pushNewThreshold = true;
239 int vecSize = m_valThreshold.size();
240 for(int k=0; k<vecSize; k++){
241 if(fabs(threshold-m_valThreshold[k])<0.1){
242 pushNewThreshold = false;
243 break;
244 }
245 }
246 if(pushNewThreshold){
247 m_valThreshold.push_back(threshold);
248 m_thIdEnd.push_back(i-1);
249 m_thIdFrom.push_back(i);
250 }
251 }
252 }
253 ftw.Close();
254 m_thIdEnd.push_back(nEntries-1);
255 if(m_printInfo){
256 cout << "Print time walk calibration info" << endl;
257 // for(int i=0; i<m_tw.size(); i++){
258 // cout << "time walk: " << setw(15)<<m_tw[i]<<setw(15)<<m_charge[i]
259 // <<setw(15)<<m_threshold[i]<<endl;
260 // }
261 for(int i=0; i<m_valThreshold.size(); i++){
262 cout << setw(10) << m_valThreshold[i] << setw(10) << m_thIdFrom[i]
263 << setw(10) << m_thIdEnd[i] << setw(15)<<m_charge[m_thIdFrom[i]]
264 << setw(15) << m_charge[m_thIdEnd[i]] << endl;
265 }
266 }
267
268 return true;
269}
270
271double CgemCalibFunSvc::getSigma(int layer, int xvFlag, int readoutMode, double angle, double Q, double T) const{
272 double sigma = 0.13; // unit: mm
273 return sigma;
274}
275
276double CgemCalibFunSvc::getTimeRising(int layer, int xvFlag, int sheet, int stripID, double Q, double z) const{
277 return m_tRising[layer][xvFlag][sheet];
278}
279
280double CgemCalibFunSvc::getTimeFalling(int layer, int xvFlag, int sheet, int stripID, double Q, double z) const{
281 return m_tFalling[layer][xvFlag][sheet];
282}
283
284double CgemCalibFunSvc::getTimeWalk(int layer, int xvFlag, int sheet, int stripID, double Q) const{
285 double tw = 0.0;
286 if(!m_readLUT){
287 cout << "ERROR: can not calculate time walk with LUT, return tw=0." << endl;
288 return tw;
289 }
290 double threshold = m_cgemLUTReader->Get_thr_T_fC(layer, sheet, xvFlag, stripID);
291 if(m_printInfo){
292 cout << setw(8)<<layer <<setw(8)<<sheet<<setw(8)<<xvFlag<<setw(8)<<stripID
293 <<setw(15)<<threshold<<endl;
294 }
295
296 tw = getTimeWalk(Q, threshold);
297 return tw;
298}
299
300double CgemCalibFunSvc::getTimeWalk(double Q, double threshold) const{
301 MsgStream log(messageService(), name());
302
303 double tw = 0.0;
304 int thresholdId = -1;
305 double minval = 1000.;
306 for(int i=0; i<m_valThreshold.size(); i++){
307 double val = fabs(threshold-m_valThreshold[i]);
308 if(val<minval){
309 minval = val;
310 thresholdId = i;
311 }
312 }
313
314 int binMin = m_thIdFrom[thresholdId];
315 int binMax = m_thIdEnd[thresholdId];
316 double qMin = m_charge[binMin];
317 double qMax = m_charge[binMax];
318
319 if(minval>1.0){
320 log << MSG::WARNING << "can not find time walk calibration constants for threshold="
321 << threshold << " , use the parameters with threshold=" << m_valThreshold[thresholdId] << endreq;
322 if(m_printInfo){
323 cout << "threshold_binId = " << thresholdId << " qMin = " << qMin
324 << " qMax = " << qMax << endl;
325 }
326 }
327
328 if(Q < 0.0){
329 log << MSG::WARNING << "charge<0, calculate time walk with charge=0" << endreq;
330 tw = (0.0-m_charge[binMin])*(m_tw[binMin]-m_tw[binMin+1])/(m_charge[binMin]-m_charge[binMin+1]) + m_tw[binMin];
331 } else if(Q < qMin){
332 log << MSG::WARNING << "charge < minimumCharge in time walk calibration function " << qMin << endreq;
333 tw = (Q-m_charge[binMin])*(m_tw[binMin]-m_tw[binMin+1])/(m_charge[binMin]-m_charge[binMin+1]) + m_tw[binMin];
334 } else if(Q > qMax){
335 log << MSG::WARNING << "charge > maximumCharge in time walk calibration function " << qMax << endreq;
336 if(m_printInfo) cout << "binMin = " << binMin << " binMax = " << binMax << endl;
337 tw = (Q-m_charge[binMax])*(m_tw[binMax]-m_tw[binMax-1])/(m_charge[binMax]-m_charge[binMax-1]) + m_tw[binMax];
338 } else{
339 for(int i=binMin; i<binMax; i++){
340 if((Q>=m_charge[i]) && (Q<m_charge[i+1])){
341 tw = (m_tw[i+1]-m_tw[i])*(Q-m_charge[i])/(m_charge[i+1]-m_charge[i]) + m_tw[i];
342 }
343 }
344 }
345
346 return tw;
347}
virtual StatusCode initialize()
double getTimeWalk(int layer, int xvFlag, int sheet, int stripID, double Q) const
CgemCalibFunSvc(const std::string &name, ISvcLocator *svcloc)
virtual StatusCode queryInterface(const InterfaceID &riid, void **ppvUnknown)
double getSigma(int layer, int xvFlag, int readoutMode, double angle, double Q, double T) const
virtual StatusCode finalize()
void handle(const Incident &)
double getTimeFalling(int layer, int xvFlag, int sheet, int stripID, double Q=100., double z=0.) const
double getTimeRising(int layer, int xvFlag, int sheet, int stripID, double Q=100., double z=0.) const
float Get_thr_T_fC(int ilayer, int isheet, int iview, int istrip)