00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00049
00050 #include "TH1.h"
00051
00052 #include "MessageService/MsgService.h"
00053 #include "Calibrator/CalVaLinearity.h"
00054 #include "PulserCalibration/PulserGainFit.h"
00055 #include "DatabaseInterface/DbiResultSet.h"
00056 #include "DatabaseInterface/DbiValidityRec.h"
00057 #include "Plex/PlexPinDiodeId.h"
00058 #include "Plex/PlexStripEndId.h"
00059 #include <math.h>
00060
00061 ClassImp(PulserGainFit)
00062
00063 CVSID("$Id: PulserGainFit.cxx,v 1.11 2007/01/23 17:01:56 rhatcher Exp $\n \
00064 CVSID_DBIRESULTPTR ");
00065
00066
00067 PulserGainFit::PulserGainFit(const Detector::Detector_t &det, VldTimeStamp &tsin, VldTimeStamp &tein)
00068 {
00069
00070
00071 fUseSameValidity = 1;
00072
00073
00074 fDetector = det;
00075 fStartin = tsin;
00076 fEndin = tein;
00077 MSG("Pulser",Msg::kInfo)<<"PulserGainFit created for detector "<<Detector::AsString(fDetector)<<endl;
00078 MSG("Pulser",Msg::kInfo)<<"Input timestart = "<<fStartin.AsString()<<endl;
00079 MSG("Pulser",Msg::kInfo)<<"Input timeend = "<<fEndin.AsString()<<endl;
00080 MSG("Pulser",Msg::kInfo)<<"Output timestart and timend will be taken from validity range of input data"<<endl;
00081
00082
00083 fStartout = fStartin;
00084 fEndout = fEndin;
00085
00086 this->Init();
00087
00088 }
00089
00090 PulserGainFit::PulserGainFit(const Detector::Detector_t &det, VldTimeStamp &tsin, VldTimeStamp &tein, VldTimeStamp &tsout, VldTimeStamp &teout)
00091 {
00092
00093
00094 fUseSameValidity = 0;
00095
00096
00097 fDetector = det;
00098 fStartin = tsin;
00099 fEndin = tein;
00100 fStartout = tsout;
00101 fEndout = teout;
00102 MSG("Pulser",Msg::kInfo)<<"PulserGainFit created for detector "<<Detector::AsString(fDetector)<<endl;
00103 MSG("Pulser",Msg::kInfo)<<"Input timestart = "<<fStartin.AsString()<<endl;
00104 MSG("Pulser",Msg::kInfo)<<"Input timeend = "<<fEndin.AsString()<<endl;
00105 MSG("Pulser",Msg::kInfo)<<"Output timestart = "<<fStartout.AsString()<<endl;
00106 MSG("Pulser",Msg::kInfo)<<"Output timeend = "<<fEndout.AsString()<<endl;
00107
00108 this->Init();
00109
00110 }
00111
00112 PulserGainFit::~PulserGainFit() {
00113 if(fFile) {
00114 fFile->Write();
00115 fFile->Close();
00116 }
00117 }
00118
00119
00120 void PulserGainFit::Init() {
00121
00122 Registry r;
00123 r.Set("WriteDB",0);
00124 r.Set("DBSimMask",5);
00125 r.Set("DBName","temp");
00126 r.Set("DBComment","");
00127 r.Set("WritePlots",0);
00128 r.Set("PlotsFile","plots.root");
00129 r.Set("Adcmin",300.);
00130 r.Set("Adcmax",8000.);
00131 r.Set("Npass",1);
00132 r.Set("MinAggNo",-1);
00133 r.Set("MaxAggNo",-1);
00134 InitializeConfig(r);
00135
00136
00137
00138 fFitLine = new TF1("line","[0]*(x-[1])");
00139 fFitLine->FixParameter(1,0.);
00140
00141
00142 fFitPole = new TF1("pole",CalVaLinearity::FitFunction,200.,15000.,8);
00143
00144 fFitPole->FixParameter(0,5.);
00145
00146 fFitPole->FixParameter(5,0.);
00147
00148 fFitPole->FixParameter(6,0.);
00149
00150 fFitPole->FixParameter(3,0.);
00151 fFitPole->FixParameter(4,0.);
00152
00153
00154 fFitPK1 = new TF1("pk1",CalVaLinearity::FitFunction,200.,15000.,8);
00155
00156 fFitPK1->FixParameter(0,25.);
00157
00158 fFitPK1->FixParameter(5,0.);
00159
00160 fFitPK1->FixParameter(6,0.);
00161
00162
00163 fFitPK2 = new TF1("pk2",CalVaLinearity::FitFunction,200.,15000.,8);
00164
00165 fFitPK2->FixParameter(0,25.);
00166
00167 fFitPK2->FixParameter(5,0.);
00168
00169 fFile = 0;
00170 fNextra = 0;
00171 }
00172
00173
00174 void PulserGainFit::ConfigModified()
00175 {
00176 fWriteDB = GetConfig().GetInt("WriteDB");
00177 fDBSimMask = GetConfig().GetInt("DBSimMask");
00178 fDBName = GetConfig().GetCharString("DBName");
00179 fDBComment = GetConfig().GetCharString("DBComment");
00180 fWritePlots = GetConfig().GetInt("WritePlots");
00181 fPlotsFile = GetConfig().GetCharString("PlotsFile");
00182 GetConfig().Get("Adcmin",fAdcmin);
00183 GetConfig().Get("Adcmax",fAdcmax);
00184 GetConfig().Get("Npass",fNpass);
00185 GetConfig().Get("MinAggNo",fMinAggNo);
00186 GetConfig().Get("MaxAggNo",fMaxAggNo);
00187
00188 fWriterl.SetDbName(fDBName);
00189 fWriterh.SetDbName(fDBName);
00190 fWriternf.SetDbName(fDBName);
00191
00192 MSG("Pulser",Msg::kInfo)<<"Configuration: WriteDB = "<<fWriteDB<<" WritePlots = " <<fWritePlots<<" Adcmin = "<<fAdcmin<<" Adcmax = "<<fAdcmax<<" Npass = "<<fNpass<<endl;
00193 if(fWriteDB > 0) {MSG("Pulser",Msg::kInfo)<<"Writing to database "<<fDBName<<" with SimMask "<<fDBSimMask<<" Comment "<<fDBComment<<endl;}
00194 if(fWritePlots > 0) {MSG("Pulser",Msg::kInfo)<<"Writing plots to "<<fPlotsFile<<endl;}
00195 }
00196
00197
00198 void PulserGainFit::AddRun(VldTimeStamp &ts, VldTimeStamp &te) {
00199
00200
00201 if(fNextra == 3) {
00202 MSG("Pulser",Msg::kError)<<"Maximum runs exceeded, ignoring run"<<endl;
00203 return;
00204 }
00205
00206
00207 if(fUseSameValidity) {
00208 MSG("Pulser",Msg::kWarning)<<"Output validity will not be changed by call to AddRun"<<endl;
00209 }
00210
00211
00212 fStartExtra[fNextra] = ts;
00213 fEndExtra[fNextra] = te;
00214 fNextra++;
00215 }
00216
00217
00218 void PulserGainFit::RunPinFits() {
00219
00220
00221 if(fWritePlots) {
00222 if(fFile == 0) {
00223 fFile = new TFile(GetConfig().GetCharString("PlotsFile"),"RECREATE");
00224 }
00225 hSlopeNL = new TH1F("hSlopeNL","hSlopeNL",100,0.,20.);
00226 hSlopeNH = new TH1F("hSlopeNH","hSlopeNH",100,0.,20.);
00227 hSlopeFL = new TH1F("hSlopeFL","hSlopeFL",100,0.,20.);
00228 hSlopeFH = new TH1F("hSlopeFH","hSlopeFH",100,0.,20.);
00229 hChisqNL = new TH1F("hChisqNL","hChisqNF",100,0.,20.);
00230 hChisqNH = new TH1F("hChisqNH","hChisqNF",100,0.,20.);
00231 hChisqFL = new TH1F("hChisqFL","hChisqNF",100,0.,20.);
00232 hChisqFH = new TH1F("hChisqFH","hChisqNF",100,0.,20.);
00233 hNumPointsNL = new TH1F("hNumPointsNL","hNumPointsNL",20,0.,20.);
00234 hNumPointsNH = new TH1F("hNumPointsNH","hNumPointsNH",20,0.,20.);
00235 hNumPointsFL = new TH1F("hNumPointsFL","hNumPointsFL",20,0.,20.);
00236 hNumPointsFH = new TH1F("hNumPointsFH","hNumPointsFH",20,0.,20.);
00237 }
00238
00239
00240
00241 VldRange range(fDetector,SimFlag::kData,fStartout,fEndout,fDBName);
00242
00243
00244 VldContext vldc(fDetector,SimFlag::kData,fStartin);
00245 PlexHandle plex(vldc);
00246
00247
00248 GetPinData();
00249
00250
00251 DbiResultPtr<PulserGain> rsStripEnd;
00252
00253
00254
00255 if (fMinAggNo < 0) {
00256 if (fDetector==Detector::kNear) fMinAggNo = 1;
00257 if (fDetector==Detector::kFar) fMinAggNo = 1;
00258 }
00259 MSG("Pulser",Msg::kInfo)<<"Set min aggregate to " << fMinAggNo << " for "<<Detector::AsString(fDetector)<< " detector." <<endl;
00260 if (fMaxAggNo < 0) {
00261 if (fDetector==Detector::kNear) fMaxAggNo = 139;
00262 if (fDetector==Detector::kFar) fMaxAggNo = 980;
00263 }
00264 MSG("Pulser",Msg::kInfo)<<"Set max aggregate to " << fMaxAggNo << " for "<<Detector::AsString(fDetector)<< " detector." <<endl;
00265
00266
00267 for (int task = 1; task <=2; task++) {
00268
00269
00270 for (int aggregateno = fMinAggNo; aggregateno <=fMaxAggNo; aggregateno++ ) {
00271
00272
00273
00274
00275
00276
00277 DbiSqlContext inContext(DbiSqlContext::kStarts,fStartin,fEndin,fDetector,SimFlag::kData);
00278 inContext << " and AGGREGATENO=" << aggregateno;
00279 MSG("Pulser",Msg::kInfo)<<"Aggregate " << aggregateno << endl;
00280 rsStripEnd.NewQuery(inContext,task);
00281 const int numStripEnd = rsStripEnd.GetNumRows();
00282 MSG("Pulser",Msg::kInfo)<<"Retrieved " << numStripEnd << " stripend rows" << endl;
00283 if (numStripEnd == 0 ) {continue;}
00284
00285
00286 if(fUseSameValidity) {
00287 const DbiValidityRec* vrec = rsStripEnd.GetValidityRec();
00288 const VldRange& vrng = vrec->GetVldRange();
00289
00290 fStartout = vrng.GetTimeStart();
00291 fEndout = fStartout;
00292 fEndout.Add(VldTimeStamp(3600*24*62,0));
00293 range.SetTimeStart(fStartout);
00294 range.SetTimeEnd(fEndout);
00295 }
00296
00297
00298 Float_t lxoff = 0.;
00299 Float_t hxoff = 0.;
00300 for (int ipass = 1; ipass <= fNpass; ipass++) {
00301
00302 if(ipass < fNpass) {fFitLine->ReleaseParameter(1);}
00303
00304
00305 if(fWriteDB > 0 && ipass == fNpass) {
00306 fWriterl.Open(range,aggregateno,task,0,fDBName);
00307 fWriterh.Open(range,aggregateno,task+2,0,fDBName);
00308 }
00309
00310
00311 for (int ir=0; ir<numStripEnd; ir++) {
00312
00313 const PulserGain* rs = rsStripEnd.GetRow(ir);
00314 int skey = rs->GetStripEnd();
00315 PlexStripEndId seid = PlexStripEndId::UnbuildPlnStripEndKey(fDetector, skey);
00316
00317
00318 if(ipass == fNpass) {fFitLine->FixParameter(1,lxoff);}
00319 Fit(*(lgpinmap.find(aggregateno)->second),*(const_cast<PulserGain*>(rs)));
00320 float lslope = fFitLine->GetParameter(0);
00321 float lslopeerr = fFitLine->GetParError(0);
00322 float lxoffset = fFitLine->GetParameter(1);
00323 float lchisq = fFitLine->GetChisquare();
00324 int lnumpoints = fFitLine->GetNumberFitPoints();
00325 MSG("Pulser",Msg::kDebug)<<"Stripend "<<seid<<" Pin "<<lgpinmap.find(aggregateno)->second->GetPinDiodeId()<<" fit slope= "<<lslope<< " xoffset= "<<lxoffset<<" numpoints = "<<lnumpoints<<endl;
00326
00327 if(fWritePlots) {
00328 if(task==1) {
00329 hSlopeNL->Fill(lslope);
00330 hChisqNL->Fill(lchisq);
00331 hNumPointsNL->Fill(lnumpoints);
00332 }
00333 if(task==2) {
00334 hSlopeFL->Fill(lslope);
00335 hChisqFL->Fill(lchisq);
00336 hNumPointsFL->Fill(lnumpoints);
00337 }
00338 }
00339
00340 if (ipass < fNpass) {
00341
00342 lxoff += lxoffset;
00343 }
00344 else {
00345
00346 if(fWriteDB) {
00347 CalPulserFits lrow(aggregateno,skey,lnumpoints,lslope,lslopeerr,lxoffset,lchisq);
00348 fWriterl << lrow;
00349 }
00350 }
00351
00352
00353 if(ipass == fNpass) {fFitLine->FixParameter(1,hxoff);}
00354 Fit(*(hgpinmap.find(aggregateno)->second),*(const_cast<PulserGain*>(rs)));
00355 float hslope = fFitLine->GetParameter(0);
00356 float hslopeerr = fFitLine->GetParError(0);
00357 float hxoffset = fFitLine->GetParameter(1);
00358 float hchisq = fFitLine->GetChisquare();
00359 int hnumpoints = fFitLine->GetNumberFitPoints();
00360 MSG("Pulser",Msg::kDebug)<<"Stripend "<<seid<<" Pin "<<hgpinmap.find(aggregateno)->second->GetPinDiodeId()<<" fit slope= "<<hslope<< " xoffset= "<<hxoffset<<" numpoints = "<<hnumpoints<<endl;
00361
00362 if(fWritePlots) {
00363 if(task==1) {
00364 hSlopeNH->Fill(hslope);
00365 hChisqNH->Fill(hchisq);
00366 hNumPointsNH->Fill(hnumpoints);
00367 }
00368 if(task==2) {
00369 hSlopeFH->Fill(hslope);
00370 hChisqFH->Fill(hchisq);
00371 hNumPointsFH->Fill(hnumpoints);
00372 }
00373 }
00374 if (ipass < fNpass) {
00375
00376 hxoff += hxoffset;
00377 }
00378 else {
00379
00380 if(fWriteDB) {
00381 CalPulserFits hrow(aggregateno,skey,hnumpoints,hslope,hslopeerr,hxoffset,hchisq);
00382 fWriterh << hrow;
00383 }
00384 }
00385 }
00386 lxoff = lxoff/(float)numStripEnd;
00387 hxoff = hxoff/(float)numStripEnd;
00388 }
00389 }
00390 }
00391
00392 if(fWriteDB) {
00393 if(fWriterl.IsOpen()) {fWriterl.Close();}
00394 if(fWriterh.IsOpen()) {fWriterh.Close();}
00395 }
00396
00397 }
00398
00399
00400 void PulserGainFit::GetPinData() {
00401
00402
00403 DbiSqlContext inContext(DbiSqlContext::kStarts,fStartin,fEndin,fDetector,SimFlag::kData);
00404
00405
00406 DbiResultPtr<PulserGainPin> rsPin("PULSERGAINPIN",inContext,Dbi::kAnyTask);
00407 const int numPin = rsPin.GetNumRows();
00408 MSG("Pulser",Msg::kInfo)<<"Retrieved " << numPin << " pin rows" << endl;
00409
00410
00411 for (int ir=0; ir<numPin; ir++) {
00412
00413 const PulserGainPin* rs = rsPin.GetRow(ir);
00414 int pingain = rs->GetPinDiodeId().GetGain();
00415 int aggregateno = rs->GetAggregateNo();
00416
00417 if (pingain == 1) {
00418 lgpinmap.insert(pair<int,PulserGainPin*>(aggregateno,const_cast<PulserGainPin*>(rs) ));
00419 }
00420
00421 if (pingain == 0) {
00422 hgpinmap.insert(pair<int,PulserGainPin*>(aggregateno,const_cast<PulserGainPin*>(rs) ));
00423 }
00424 }
00425
00426 }
00427
00428
00429 void PulserGainFit::Fit(PulserGainPin &pin, PulserGain &stripend){
00430
00431
00432
00433 assert(stripend.GetNumPoints()==pin.GetNumPoints());
00434 assert(stripend.GetAggregateNo()==pin.GetAggregateNo());
00435
00436
00437
00438
00439
00440
00441 Float_t x[40];
00442 Float_t y[40];
00443 Float_t er_x[40];
00444 Float_t er_y[40];
00445 for(int i=0; i<pin.GetNumPoints(); i++) {
00446 x[i] = pin.ZCMean(i);
00447 y[i] = stripend.ZCMean(i);
00448 er_x[i] = pin.ZCError(i);
00449 er_y[i] = stripend.ZCError(i);
00450 }
00451 TGraphErrors g(pin.GetNumPoints(),x,y,er_x,er_y);
00452
00453
00454 float xmin = fAdcmin;
00455 float xmax = fAdcmax;
00456 for (int i=0;i<pin.GetNumPoints();i++) {
00457 if (y[i] < fAdcmin && x[i] > fAdcmin) xmin =x[i]+1;
00458 if (y[i] > fAdcmax && x[i] < fAdcmax) {
00459 xmax = x[i]-1;
00460 break;
00461 }
00462 }
00463
00464
00465 fFitLine->SetRange(fAdcmin,fAdcmax);
00466
00467
00468 fFitLine->SetParameter(0,1.);
00469
00470
00471 g.Fit(fFitLine,"Q"," ",xmin,xmax);
00472
00473 }
00474
00475
00476 void PulserGainFit::RunNearFarFits() {
00477
00478
00479 if(fWritePlots) {
00480 if(fFile==0) {
00481 fFile = new TFile(GetConfig().GetCharString("PlotsFile"),"RECREATE");
00482 }
00483 fNearFarTree = new TTree("nftree","Near-Far fits");
00484 fNearFarTree->Branch("plane",&fPlane,"plane/I");
00485 fNearFarTree->Branch("strip",&fStrip,"strip/I");
00486 fNearFarTree->Branch("bay",&fBay,"bay/I");
00487 fNearFarTree->Branch("rack",&fRack,"rack/I");
00488 fNearFarTree->Branch("tube",&fTube,"tube/I");
00489 fNearFarTree->Branch("pixel",&fPixel,"pixel/I");
00490 fNearFarTree->Branch("spot",&fSpot,"spot/I");
00491 fNearFarTree->Branch("pb",&fPb,"pb/I");
00492 fNearFarTree->Branch("led",&fLed,"led/I");
00493 fNearFarTree->Branch("adcmin",&fMinadc,"adcmin/F");
00494 fNearFarTree->Branch("adcmax",&fMaxadc,"adcmin/F");
00495 fNearFarTree->Branch("ftype",&fFtype,"ftype/I");
00496 fNearFarTree->Branch("npar",&fNpar,"npar/I");
00497 fNearFarTree->Branch("npfit",&fNpfit,"npfit/I");
00498 fNearFarTree->Branch("gain",&fGain,"gain/F");
00499 fNearFarTree->Branch("ped",&fPed,"ped/F");
00500 fNearFarTree->Branch("dped",&fDped,"dped/F");
00501 fNearFarTree->Branch("k1",&fK1,"k1/F");
00502 fNearFarTree->Branch("k2",&fK2,"k2/F");
00503 fNearFarTree->Branch("k3",&fK3,"k3/F");
00504 fNearFarTree->Branch("k4",&fK4,"k4/F");
00505 fNearFarTree->Branch("chisq",&fChisq,"chisq/F");
00506 fNearFarTree->Branch("meanres",&fMeanres,"meanres/F");
00507 fNearFarTree->Branch("maxres",&fMaxres,"maxres/F");
00508 fNearFarTree->Branch("delta200",&fDelta200,"delta200/F");
00509 fNearFarTree->Branch("delta7500",&fDelta7500,"delta7500/F");
00510 }
00511
00512
00513
00514 VldRange range(fDetector,fDBSimMask,fStartout,fEndout,fDBName);
00515
00516
00517 VldContext vldc(fDetector,SimFlag::kData,fStartin);
00518 PlexHandle plex(vldc);
00519
00520
00521 DbiResultPtr<PulserGain> rsStripEndf[3];
00522 DbiResultPtr<PulserGain> rsStripEndn[3];
00523
00524
00525
00526 if (fMinAggNo < 0) {
00527 if (fDetector==Detector::kNear) fMinAggNo = 1;
00528 if (fDetector==Detector::kFar) fMinAggNo = 1;
00529 }
00530 MSG("Pulser",Msg::kInfo)<<"Set min aggregate to " << fMinAggNo << " for "<<Detector::AsString(fDetector)<< " detector." <<endl;
00531 if (fMaxAggNo < 0) {
00532 if (fDetector==Detector::kNear) fMaxAggNo = 139;
00533 if (fDetector==Detector::kFar) fMaxAggNo = 980;
00534 }
00535 MSG("Pulser",Msg::kInfo)<<"Set max aggregate to " << fMaxAggNo << " for "<<Detector::AsString(fDetector)<< " detector." <<endl;
00536
00537
00538 for (int aggregateno = fMinAggNo; aggregateno <=fMaxAggNo; aggregateno++ ) {
00539 DbiSqlContext inContext(DbiSqlContext::kStarts,fStartin,fEndin,fDetector,SimFlag::kData);
00540 inContext << " and AGGREGATENO=" << aggregateno;
00541 MSG("Pulser",Msg::kInfo)<<"Aggregate " << aggregateno << endl;
00542 rsStripEndn[0].NewQuery(inContext,Pulser::kNearEnd);
00543 const int numStripEndn = rsStripEndn[0].GetNumRows();
00544 rsStripEndf[0].NewQuery(inContext,Pulser::kFarEnd);
00545 const int numStripEndf = rsStripEndf[0].GetNumRows();
00546 MSG("Pulser",Msg::kInfo)<<"Retrieved "<<numStripEndn<<" Near stripend rows and "<<numStripEndf<< " Far stripend rows"<< endl;
00547 if (numStripEndn == 0 || numStripEndf == 0 ) {continue;}
00548
00549
00550 if(fUseSameValidity) {
00551 const DbiValidityRec* vrec = rsStripEndn[0].GetValidityRec();
00552 const VldRange& vrng = vrec->GetVldRange();
00553 fStartout = vrng.GetTimeStart();
00554 fEndout = fStartout;
00555 fEndout.Add(VldTimeStamp(3600*24*62,0));
00556 range.SetTimeStart(fStartout);
00557 range.SetTimeEnd(fEndout);
00558 }
00559
00560
00561 if(fWriteDB) {
00562 Bool_t iok = fWriternf.Open(range,aggregateno,5,0,fDBName,fDBComment);
00563 if(!iok) {MSG("Pulser",Msg::kError)<<"Dbiwriter error"<< endl;}
00564 }
00565
00566
00567 if(fNextra>0) {
00568 for(int j=0; j<fNextra; j++) {
00569 DbiSqlContext context(DbiSqlContext::kStarts,fStartExtra[j],fEndExtra[j],fDetector,SimFlag::kData);
00570 context << " and AGGREGATENO=" << aggregateno;
00571 rsStripEndn[j+1].NewQuery(context,Pulser::kNearEnd);
00572 const int numn = rsStripEndn[j+1].GetNumRows();
00573 rsStripEndf[j+1].NewQuery(context,Pulser::kFarEnd);
00574 const int numf = rsStripEndf[j+1].GetNumRows();
00575 MSG("Pulser",Msg::kInfo)<<"Retrieved "<<numn<<" Near stripend rows and "<<numf<< " Far stripend rows"<< endl;
00576 }
00577 }
00578
00579
00580 Double_t x[60];
00581 Double_t er_x[60];
00582
00583
00584 Int_t test = FarMeans(rsStripEndf,x,er_x);
00585 if(test != 0) {
00586 MSG("Pulser",Msg::kInfo)<<"Aggregate "<<aggregateno<<" Far Fits failed, ngood = "<<test<<endl;
00587 continue;
00588 }
00589
00590 const PulserGain* rsn[3];
00591
00592
00593 for (int ir=0; ir<numStripEndn; ir++) {
00594
00595 rsn[0] = rsStripEndn[0].GetRow(ir);
00596 int skey = rsn[0]->GetStripEnd();
00597
00598
00599 for (int j=1; j<3; j++) {rsn[j] = 0;}
00600 if(fNextra>0) {
00601 for (int j=1; j<=fNextra; j++) {
00602 rsn[j] = rsStripEndn[j].GetRowByIndex(skey);
00603 }
00604 }
00605
00606 Double_t y[60];
00607 Double_t er_y[60];
00608 Int_t ntot = 0;
00609 for (int j=0; j<fNextra+1; j++) {
00610 for(int i=0; i<rsn[j]->GetNumPoints(); i++) {
00611 y[ntot+i] = rsn[j]->ZCMean(i);
00612 er_y[ntot+i] = rsn[j]->ZCError(i);
00613
00614 if(er_y[ntot+i]<0.003*y[ntot+i]) {er_y[ntot+i] = 0.003*y[ntot+i];}
00615 }
00616 ntot += rsn[j]->GetNumPoints();
00617 }
00618 fMinadc = y[0];
00619 fMaxadc = y[ntot-1];
00620
00621 TGraphErrors* g = new TGraphErrors(ntot,x,y,er_x,er_y);
00622
00623 fFtype = Fit(g);
00624
00625 if(fWriteDB) {
00626 CalPulserFits row(aggregateno,skey,fFtype,fFit,fMeanRes,fMaxRes,fMaxadc);
00627 fWriternf << row;
00628 }
00629
00630 if(fNearFarTree!=0) {
00631 PlexStripEndId seid = PlexStripEndId::UnbuildPlnStripEndKey(fDetector, skey);
00632 fPlane = seid.GetPlane();
00633 fStrip = seid.GetStrip();
00634 PlexPixelSpotId spotid = plex.GetPixelSpotId(seid);
00635 fBay = spotid.GetRackBay();
00636 fRack = spotid.GetInRack();
00637 fTube = spotid.GetTube();
00638 fPixel = spotid.GetPixel();
00639 fSpot = spotid.GetSpot();
00640 PlexLedId ledid = plex.GetLedId(seid);
00641 fPb = ledid.GetPulserBox();
00642 fLed = ledid.GetLedInBox();
00643
00644 if(fFtype < -25 || fFit == 0) {
00645 fNpar = 0;
00646 fNpfit = 0;
00647 fGain = 0;
00648 fPed = 0;
00649 fDped = 0;
00650 fK1 = 0;
00651 fK2 = 0;
00652 fK3 = 0;
00653 fK4 = 0;
00654 fChisq = 0;
00655 fDelta200 = 0;
00656 fDelta7500 = 0;
00657 }
00658
00659 if(abs(fFtype) == 1) {
00660 fNpar = 1;
00661 fNpfit = fFit->GetNumberFitPoints();
00662 fGain = 1.0/fFit->GetParameter(0);
00663 fPed = fFit->GetParError(0);
00664 fDped = fFit->GetParameter(1);
00665 fK1 = 0;
00666 fK2 = 0;
00667 fK3 = 0;
00668 fK4 = 0;
00669 fChisq = fFit->GetChisquare();
00670 fDelta200 = 0;
00671 fDelta7500 = 0;
00672 }
00673 if(abs(fFtype) == 5 || abs(fFtype) == 25) {
00674 fNpar = fFit->GetNumberFreeParameters()+1;
00675 fNpfit = fFit->GetNumberFitPoints();
00676 fGain = fFit->GetParameter(7);
00677 fPed = fFit->GetParameter(6);
00678 fDped = fFit->GetParError(6);
00679 fK1 = fFit->GetParameter(1);
00680 fK2 = fFit->GetParameter(2);
00681 if(abs(fFtype) == 25) {
00682 fK3 = fFit->GetParameter(3);
00683 fK4 = fFit->GetParameter(4);
00684 }
00685 else {
00686 fK3 = 0;
00687 fK4 = 0;
00688 }
00689 fChisq = fFit->GetChisquare();
00690 Double_t par[8];
00691 for (int j=0; j<8; j++) {par[j] = fFit->GetParameter(j);}
00692 par[0] -= 1.;
00693 Double_t xtest = 200.;
00694 Double_t ytest = (CalVaLinearity::FitFunction(&xtest,par)-par[6])/par[7];
00695 fDelta200 = 100.*(ytest-xtest)/xtest;
00696 xtest = 7500.;
00697 ytest = (CalVaLinearity::FitFunction(&xtest,par)-par[6])/par[7];
00698 fDelta7500 = 100.*(ytest-xtest)/xtest;
00699 }
00700 fMeanres = fMeanRes;
00701 fMaxres = fMaxRes;
00702 fNearFarTree->Fill();
00703 }
00704 delete g;
00705 }
00706 }
00707
00708 if(fWriteDB) {
00709 if(fWriternf.IsOpen()) {fWriternf.Close();}
00710 }
00711 }
00712
00713 Int_t PulserGainFit::FarMeans(DbiResultPtr<PulserGain> rsPtrf[3], Double_t* x, Double_t* er_x) {
00714
00715
00716 Int_t numRowsf = rsPtrf[0].GetNumRows();
00717
00718
00719 const PulserGain* rs[3];
00720
00721
00722 Int_t sgood[1000];
00723 for(int i=0; i<1000; i++) {sgood[i]=0;}
00724 Int_t ngood = 0;
00725
00726
00727 fFitLine->FixParameter(1,0.);
00728
00729
00730 Int_t nitmax = 3;
00731 Int_t ngood_last = numRowsf;
00732 for(int it=0; it<nitmax; it++) {
00733
00734
00735 ngood = 0;
00736 for(int i=0; i<60; i++) {
00737 x[i] = 0.;
00738 er_x[i] = 0.;
00739 }
00740
00741 for (int ir = 0; ir < numRowsf; ++ir) {
00742
00743 rs[0] = rsPtrf[0].GetRow(ir);
00744 Int_t skey = rs[0]->GetStripEnd();
00745
00746
00747 if(sgood[ir]!=0) {continue;}
00748 Int_t nmax = rs[0]->GetNumPoints() - 1;
00749 Float_t adcmax = rs[0]->ZCMean(nmax);
00750
00751 for (int j=1; j<3; j++) {rs[j] = 0;}
00752 if(fNextra > 0) {
00753 for (int j=1; j<=fNextra; j++) {
00754 rs[j] = rsPtrf[j].GetRowByIndex(skey);
00755 nmax = rs[j]->GetNumPoints() - 1;
00756 if(rs[j]->ZCMean(nmax) > adcmax) {adcmax = rs[j]->ZCMean(nmax);}
00757 }
00758 }
00759 if(adcmax<1000 || adcmax>6000) {continue;}
00760 ngood++;
00761
00762 Int_t ntot = 0;
00763 for (int j=0; j<fNextra+1; j++) {
00764 for(int i=0; i<rs[j]->GetNumPoints(); i++) {
00765 Double_t error = rs[j]->ZCError(i);
00766 x[ntot+i] += rs[j]->ZCMean(i)/(error*error);
00767 er_x[ntot+i] += 1./(error*error);
00768 }
00769 ntot += rs[j]->GetNumPoints();
00770 }
00771 }
00772
00773
00774 for(int i=0; i<60; i++) {
00775 if(er_x[i] > 0.) {
00776 x[i] = x[i] / er_x[i];
00777 er_x[i] = 1./sqrt(er_x[i]);
00778 }
00779 }
00780
00781
00782 if(ngood_last-ngood < 0.01*ngood_last) {break;}
00783 ngood_last = ngood;
00784
00785
00786 for (int ir = 0; ir < numRowsf; ++ir) {
00787
00788 rs[0] = rsPtrf[0].GetRow(ir);
00789 Int_t skey = rs[0]->GetStripEnd();
00790
00791
00792 Double_t y[60];
00793 Double_t er_y[60];
00794 for(int i=0; i<rs[0]->GetNumPoints(); i++) {
00795 y[i] = rs[0]->ZCMean(i);
00796 er_y[i] = rs[0]->ZCError(i);
00797 }
00798 Int_t ntot = rs[0]->GetNumPoints();
00799 if(fNextra > 0) {
00800 for (int j=1; j<=fNextra; j++) {
00801 rs[j] = rsPtrf[j].GetRowByIndex(skey);
00802 for(int i=0; i<rs[j]->GetNumPoints(); i++) {
00803 y[ntot+i] = rs[j]->ZCMean(i);
00804 er_y[ntot+i] = rs[j]->ZCError(i);
00805 }
00806 ntot += rs[j]->GetNumPoints();
00807 }
00808 }
00809
00810
00811 TGraphErrors* g = new TGraphErrors(ntot,x,y,er_x,er_y);
00812
00813
00814 Int_t ifit = LineFit(g,fFitLine);
00815
00816
00817 if(ifit==0) {
00818 if(fFitLine->GetNumberFitPoints()<5) {
00819 sgood[ir] = 1;
00820 }
00821 else {
00822 if(fFitLine->GetChisquare()/(fFitLine->GetNumberFitPoints()-1.)>2.) {
00823 sgood[ir] = 2;
00824 }
00825 }
00826 }
00827 else {sgood[ir] = 3;}
00828
00829 delete g;
00830 }
00831 }
00832 MSG("Pulser",Msg::kInfo)<<"FarMeans: ngood = "<<ngood<<endl;
00833 if( ngood > 50) {
00834 return 0;
00835 }
00836 else {
00837 return ngood;
00838 }
00839 }
00840
00841 Int_t PulserGainFit::LineFit(TGraphErrors* g, TF1* fFitLine) {
00842
00843 Int_t n = g->GetN();
00844 Double_t* x = g->GetX();
00845 Double_t* y = g->GetY();
00846
00847
00848 float xmin = fAdcmin;
00849 float xmax = fAdcmax;
00850 float ymin = fAdcmin;
00851 float ymax = fAdcmax;
00852 int imin = -1;
00853 int imax = n-1;
00854 for (int i=0;i<n;i++) {
00855 if (x[i] > fAdcmin && y[i] > fAdcmin) {
00856 imin = i;
00857 if(i>0) {
00858 xmin = 0.5*(x[i-1]+x[i]);
00859 ymin = 0.5*(y[i-1]+y[i]);
00860 }
00861 break;
00862 }
00863 }
00864 for (int i=0;i<n;i++) {
00865 if (x[i] > fAdcmax || y[i] > fAdcmax) {
00866 imax = i-1;
00867 if (i>0) {
00868 xmax = 0.5*(x[i-1]+x[i]);
00869 ymax = 0.5*(y[i-1]+y[i]);
00870 }
00871 break;
00872 }
00873 }
00874
00875
00876
00877 fFitLine->SetParameter(0,1.);
00878
00879
00880 if(imin>=0 && imax>imin) {
00881 g->Fit(fFitLine,"Q"," ",xmin,xmax);
00882 return 0;
00883 }
00884 return 1;
00885 }
00886
00887
00888 Int_t PulserGainFit::Fit(TGraphErrors* g)
00889 {
00890
00891 Int_t ftype = -100;
00892 Int_t npar = 0;
00893 Int_t npfit = 0;
00894 Double_t gain = 0.;
00895 Double_t gain_frac_err = 0.;
00896 Double_t k1;
00897 Double_t k2;
00898 Double_t chisq = 9999.;
00899 Double_t par[8];
00900 for (int j=0; j<8; j++) {par[j] = 0.;}
00901 Float_t sres = 0.;
00902 Float_t mres = 0.;
00903
00904
00905 Int_t n = g->GetN();
00906 Double_t* x = g->GetX();
00907 Double_t* er_x = g->GetEX();
00908 Double_t* y = g->GetY();
00909 Double_t* er_y = g->GetEY();
00910
00911
00912
00913
00914 Double_t xmin = fAdcmin;
00915 Double_t ymin = fAdcmin;
00916 Int_t imin = -1;
00917 for (int i=0;i<n;i++) {
00918 if (x[i] > fAdcmin && y[i] > fAdcmin) {
00919 imin = i;
00920 if(i>0) {
00921 xmin = 0.5*(x[i-1]+x[i]);
00922 ymin = 0.5*(y[i-1]+y[i]);
00923 }
00924 break;
00925 }
00926 }
00927
00928
00929
00930 if(imin<0) {return ftype;}
00931
00932
00933 Int_t imax = n-1;
00934 Double_t xmax = x[imax]+1.;
00935 Double_t ymax = y[imax]+1.;
00936
00937
00938 fFitLine->SetParameter(0,5.);
00939 if(imax>=imin) {
00940 g->Fit(fFitLine,"Q"," ",xmin,xmax);
00941 fFit = fFitLine;
00942 ftype = 1;
00943 npar = 1;
00944 npfit = fFitLine->GetNumberFitPoints();
00945 gain = 1.0/fFitLine->GetParameter(0);
00946 gain_frac_err = fFitLine->GetParError(0)/fFitLine->GetParameter(0);
00947 chisq = fFitLine->GetChisquare();
00948 Float_t slope = fFitLine->GetParameter(0);
00949 sres = 0.;
00950 mres = 0.;
00951 for (int i=imin; i<=imax; i++) {
00952 Float_t res = y[i] - slope*x[i];
00953 if(slope*x[i]!=0) {res=100.*res/(slope*x[i]);}
00954 sres+=fabs(res);
00955 if(fabs(res)>mres) {mres = fabs(res);}
00956 }
00957 sres/=(imax-imin+1);
00958 fMeanRes = sres;
00959 fMaxRes = mres;
00960 }
00961 else {
00962
00963 return ftype;
00964 }
00965
00966
00967 if(npfit < 3) {
00968 ftype = -1;
00969 return ftype;
00970 }
00971
00972
00973 if(chisq/(npfit-npar)<2) {return ftype;}
00974
00975
00976 if(y[n-1] < 7000) {return ftype;}
00977
00978
00979
00980
00981 xmax = fAdcmax;
00982 ymax = fAdcmax;
00983 for (int i=0;i<n;i++) {
00984 if (x[i] > fAdcmax || y[i] > fAdcmax) {
00985 imax = i-1;
00986 if (i>0) {
00987 xmax = 0.5*(x[i-1]+x[i]);
00988 ymax = 0.5*(y[i-1]+y[i]);
00989 }
00990 break;
00991 }
00992 }
00993
00994
00995 fFitLine->SetParameter(0,5.);
00996 if(imax>=imin) {
00997 g->Fit(fFitLine,"Q"," ",xmin,xmax);
00998 fFit = fFitLine;
00999 ftype = 1;
01000 npar = 1;
01001 npfit = fFitLine->GetNumberFitPoints();
01002 gain = 1.0/fFitLine->GetParameter(0);
01003 gain_frac_err = fFitLine->GetParError(0)/fFitLine->GetParameter(0);
01004 chisq = fFitLine->GetChisquare();
01005 Float_t slope = fFitLine->GetParameter(0);
01006 sres = 0.;
01007 mres = 0.;
01008 for (int i=imin; i<=imax; i++) {
01009 Float_t res = y[i] - slope*x[i];
01010 if(slope*x[i]!=0) {res=100.*res/(slope*x[i]);}
01011 sres+=fabs(res);
01012 if(fabs(res)>mres) {mres = fabs(res);}
01013 }
01014 sres/=(imax-imin+1);
01015 fMeanRes = sres;
01016 fMaxRes = mres;
01017 }
01018 else {
01019
01020 ftype = -100;
01021 return ftype;
01022 }
01023
01024
01025 if( gain != 0) {
01026 for (int i=0;i<n;i++) {
01027 x[i] /= gain;
01028 er_x[i] /= gain;
01029 g->SetPoint(i,x[i],y[i]);
01030 g->SetPointError(i,er_x[i],er_y[i]);
01031 }
01032 xmin /= gain;
01033 }
01034 else {
01035 MSG("Pulser",Msg::kWarning)<<"Zero gain after linear fit"<<endl;
01036 }
01037
01038
01039
01040 imax = n-1;
01041 xmax = x[imax]+1.;
01042 ymax = y[imax]+1.;
01043
01044
01045 if(imax-imin<3) {
01046 ftype = -1;
01047 return ftype;
01048 }
01049
01050
01051 fFitPole->SetParameter(1,15000.);
01052 fFitPole->SetParameter(2,5.);
01053 if(gain != 0.) {
01054 fFitPole->FixParameter(7,1.0);
01055 }
01056 else {
01057
01058 fFitPole->ReleaseParameter(7);
01059 fFitPole->SetParameter(7,1.0);
01060 }
01061
01062
01063 g->Fit(fFitPole,"Q"," ",xmin,xmax);
01064
01065
01066
01067 if(npfit==fFitPole->GetNumberFitPoints()) {
01068 if(chisq/(npfit-npar) - fFitPole->GetChisquare()/(fFitPole->GetNumberFitPoints()-3) < 0.25) {
01069 return ftype;
01070 }
01071 }
01072
01073
01074 fFitPole->SetParError(7,gain_frac_err);
01075
01076
01077 ftype = 5;
01078 npar = 3;
01079 fFit = fFitPole;
01080 npfit = fFitPole->GetNumberFitPoints();
01081 gain = fFitPole->GetParameter(7);
01082 k1 = fFitPole->GetParameter(1);
01083 k2 = fFitPole->GetParameter(2);
01084 chisq = fFitPole->GetChisquare();
01085 for (int j=0; j<8; j++) {par[j] = fFitPole->GetParameter(j);}
01086 sres = 0.;
01087 mres = 0.;
01088 for (int i=imin; i<=imax; i++) {
01089 Double_t fy = CalVaLinearity::FitFunction(&x[i],par);
01090 Float_t res = y[i] - fy;
01091 if(fy!=0) {res=100.*res/fy;}
01092 sres+=fabs(res);
01093 if(fabs(res)>mres) {mres = fabs(res);}
01094 }
01095 sres/=(imax-imin+1);
01096 fMeanRes = sres;
01097 fMaxRes = mres;
01098
01099 par[0] -= 1.;
01100 Double_t xtest = 200.;
01101 Double_t ytest = CalVaLinearity::FitFunction(&xtest,par)/par[7];
01102 if(fabs(ytest-xtest)/xtest > 0.01) ftype = -ftype;
01103 xtest = 7500.;
01104 ytest = CalVaLinearity::FitFunction(&xtest,par)/par[7];
01105 if(fabs(ytest-xtest)/xtest > 0.10) ftype = -ftype;
01106
01107
01108 if(imax-imin<5) {return ftype;}
01109
01110
01111
01112 if(chisq < 10*(npfit-npar)) {
01113 fFitPK1->SetParameter(1,k1);
01114 fFitPK1->SetParameter(2,k2);
01115 }
01116 else {
01117 fFitPK1->SetParameter(1,15000.);
01118 fFitPK1->SetParameter(2,5.);
01119 }
01120 fFitPK1->SetParameter(3,6000.);
01121 fFitPK1->SetParameter(4,50000.);
01122 if(gain != 0.) {
01123 fFitPK1->FixParameter(7,1.0);
01124 }
01125 else {
01126 fFitPK1->ReleaseParameter(7);
01127 fFitPK1->SetParameter(7,1.0);
01128 }
01129
01130
01131 g->Fit(fFitPK1,"Q+"," ",xmin,xmax);
01132
01133
01134 fFitPK1->SetParError(7,gain_frac_err);
01135
01136
01137 if((chisq/(npfit-npar) > fFitPK1->GetChisquare()/(fFitPK1->GetNumberFitPoints()-5)) || ftype < 0) {
01138 ftype = 25;
01139 npar = 5;
01140 fFit = fFitPK1;
01141 npfit = fFitPK1->GetNumberFitPoints();
01142 gain = fFitPK1->GetParameter(7);
01143 k1 = fFitPK1->GetParameter(1);
01144 k2 = fFitPK1->GetParameter(2);
01145 chisq = fFitPK1->GetChisquare();
01146 for (int j=0; j<8; j++) {par[j] = fFitPK1->GetParameter(j);}
01147 Float_t sres = 0.;
01148 Float_t mres = 0.;
01149 for (int i=imin; i<=imax; i++) {
01150 Double_t fy = CalVaLinearity::FitFunction(&x[i],par);
01151 Float_t res = y[i] - fy;
01152 if(fy!=0) {res=100.*res/fy;}
01153 sres+=fabs(res);
01154 if(fabs(res)>mres) {mres = fabs(res);}
01155 }
01156 sres/=(imax-imin+1);
01157 fMeanRes = sres;
01158 fMaxRes = mres;
01159
01160 par[0] -= 1.;
01161 Double_t xtest = 200.;
01162 Double_t ytest = CalVaLinearity::FitFunction(&xtest,par)/par[7];
01163 if(fabs(ytest-xtest)/xtest > 0.01) ftype = -ftype;
01164 xtest = 7500.;
01165 ytest = CalVaLinearity::FitFunction(&xtest,par)/par[7];
01166 if(fabs(ytest-xtest)/xtest > 0.10) ftype = -ftype;
01167 }
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225 return ftype;
01226 }
01227