00001 #include "PhotonStatSummarizer.h"
00002 #include "PulserCalibration/PulserConventions.h"
00003 #include "Calibrator/ValueErr.h"
00004 #include "Calibrator/CalPmtDrift.h"
00005 #include "Calibrator/Calibrator.h"
00006 #include "DatabaseInterface/DbiResultPtr.h"
00007 #include "DatabaseInterface/DbiSqlContext.h"
00008 #include "DatabaseInterface/DbiWriter.h"
00009 #include "DatabaseInterface/DbiStatement.h"
00010 #include "DatabaseInterface/DbiTableProxyRegistry.h"
00011 #include "DatabaseInterface/DbiCascader.h"
00012 #include <TFile.h>
00013 #include <TTree.h>
00014 #include <iostream>
00015 #include <TH1.h>
00016 #include "MessageService/MsgService.h"
00017 #include <cmath>
00018
00019 CVSID( " $Id: PhotonStatSummarizer.cxx,v 1.25 2006/05/27 10:05:44 rhatcher Exp $ " );
00020
00021 using namespace std;
00022
00023 ClassImp(PhotonStatSummarizer)
00024 ClassImp(SpotDrift)
00025 ClassImp(PmtDrift)
00026 ClassImp(DetectorDrift)
00027
00028
00029 bool operator<(const SpotDrift& lhs, const SpotDrift& rhs)
00030 {
00031
00032 if((lhs.bad>0) != (rhs.bad>0)){
00033 if(rhs.bad>0) return true;
00034 else return false;
00035 }
00036 return (lhs.gain.GetError() < rhs.gain.GetError());
00037 }
00038
00039 void PmtDrift::Print(const char*) const
00040 {
00041 cout << "PmtDrift " << pmt.AsString() << "(" << encoded << ") "
00042 << rawGain << " " << meanGain << " " << nspot << " " << ngood
00043 << endl;
00044 }
00045
00046
00047 FloatErr GetWeightedMean(std::vector<SpotDrift>::const_iterator begin,
00048 std::vector<SpotDrift>::const_iterator end)
00049 {
00060 double n=0;
00061 double b=0;
00062 double c=0;
00063
00064 std::vector<SpotDrift>::const_iterator d = begin;;
00065 for(; d!=end; ++d) {
00066 n+=1.0;
00067
00068 double s2 = 9.92e3/(d->n);
00069 b+=d->gain.GetValue() / s2;
00070 c+=1.0/s2;
00071 }
00072
00073 if(n<1) {
00074 return FloatErr(0,0);
00075 }
00076
00077 return FloatErr((float)(b/c),
00078 (float)sqrt(1/c));
00079
00080 }
00081
00082
00083
00084 PhotonStatSummarizer::PhotonStatSummarizer()
00085 {
00086 CreateTables();
00087
00088 fTask = CalPmtDrift::kPhotonStat;
00089 if(fWhichEnd==Pulser::kFarEnd) fTask = CalPmtDrift::kPhotonStatFarEnd;
00090
00091 Registry r;
00092 r.Set("WriteDB",1);
00093 r.Set("OverwriteDB",0);
00094 r.Set("WriteDetTree",1);
00095 r.Set("WritePmtTree",1);
00096 r.Set("WriteSpotTree",0);
00097 r.Set("FileName","drifts.root");
00098 r.Set("Prescale",0);
00099 r.Set("WhichEnd",Pulser::kNearEnd);
00100
00101 InitializeConfig(r);
00102
00103 fDetTree = fPmtTree = fSpotTree = 0;
00104 fFile = 0;
00105 }
00106
00107 void PhotonStatSummarizer::ConfigModified()
00108 {
00109 fWriteDB = GetConfig().GetInt("WriteDB");
00110 fOverwriteDB = GetConfig().GetInt("OverwriteDB");
00111 fWriteDetTree = GetConfig().GetInt("WriteDetTree");
00112 fWritePmtTree = GetConfig().GetInt("WritePmtTree");
00113 fWriteSpotTree = GetConfig().GetInt("WriteSpotTree");
00114 fPrescale = GetConfig().GetInt("Prescale");
00115 fWhichEnd = GetConfig().GetInt("WhichEnd");
00116
00117 }
00118
00119
00120 PhotonStatSummarizer::~PhotonStatSummarizer()
00121 {
00122 if(fDetTree) {
00123 MSG("PmtDrift",Msg::kInfo) << "Writing Detector tree data." << endl;
00124 fDetTree->Write("",TObject::kOverwrite);
00125 }
00126
00127 if(fPmtTree) {
00128 MSG("PmtDrift",Msg::kInfo) << "Writing PMT tree data." << endl;
00129 fPmtTree->Write("",TObject::kOverwrite);
00130 }
00131
00132 if(fSpotTree) {
00133 MSG("PmtDrift",Msg::kInfo) << "Writing PixelSpot tree data." << endl;
00134 fSpotTree->Write("",TObject::kOverwrite);
00135 }
00136
00137 if(fFile) {
00138 MSG("PmtDrift",Msg::kInfo) << "Closing file." << endl;
00139 fFile->Write();
00140 delete fFile;
00141 };
00142 }
00143
00144
00145
00146
00147 void PhotonStatSummarizer::SummarizePoint(
00148 VldContext vldPointStart,
00149 VldContext vldPoint
00150 )
00151 {
00152 MSG("PmtDrift",Msg::kInfo) << endl;
00153 MSG("PmtDrift",Msg::kInfo) << "Looking at drift point starting " << vldPointStart.AsString() << endl;
00154
00155 const int kGoodVersion = 2;
00156 const int kCurrentVersion = 4;
00157
00158 if(fPrescale) {
00159 static int iteration = 0;
00160 iteration++;
00161 if((iteration % fPrescale)!=0) {
00162 MSG("PmtDrift",Msg::kInfo) << "--Prescaling away " << vldPointStart.AsString() << endl;
00163 return;
00164 }
00165 }
00166
00167 if(fWriteDB) {
00168 if(!fOverwriteDB) {
00169 for(int iVersion=kGoodVersion; iVersion<=kCurrentVersion; iVersion++){
00170 if(DoesTableExist(iVersion, vldPointStart, fTask)) {
00171 MSG("PmtDrift",Msg::kInfo) << "Skipping drift point at " << vldPointStart.AsString()
00172 << " because version " << iVersion << " data already exists." << endl;
00173 return;
00174 }
00175 }
00176 }
00177 }
00178
00179
00180 LoadDataFromDB(vldPoint);
00181
00182
00183 ComputePmtDrifts();
00184
00185 ComputeDetectorDrift();
00186
00187 if(fWriteDB) {
00188
00189 FillPmtDatabase(kCurrentVersion, vldPointStart, fTask);
00190 };
00191
00192 if(fWritePmtTree||fWriteSpotTree||fWriteDetTree)
00193 FillTrees(vldPoint);
00194
00195 }
00196
00197
00198 void PhotonStatSummarizer::CreateTables()
00199 {
00200
00201
00202 DbiStatement* s = DbiTableProxyRegistry::Instance()
00203 .GetCascader()
00204 .CreateStatement(0);
00205
00206
00207
00208
00209
00210 s->ExecuteUpdate("create table if not exists CALPMTDRIFTVLD ("
00211 " SEQNO int not null primary key auto_increment,"
00212 " TIMESTART datetime not null,"
00213 " TIMEEND datetime not null,"
00214 " DETECTORMASK tinyint,"
00215 " SIMMASK tinyint,"
00216 " TASK int,"
00217 " AGGREGATENO int,"
00218 " CREATIONDATE datetime not null,"
00219 " INSERTDATE datetime not null )");
00220
00221 s->ExecuteUpdate("create table if not exists CALPMTDRIFT ("
00222 " SEQNO integer,"
00223 " ROW_COUNTER int, "
00224 " PMT bigint, "
00225 " CHANNEL bigint,"
00226 " DRIFT float, "
00227 " STATERROR float,"
00228 " SYSERROR float,"
00229 " SPOTSUSED float,"
00230 " SPOTSAVAIL float,"
00231 " CRUDEDRIFT float,"
00232 " MINDRIFT float,"
00233 " MAXDRIFT float,"
00234 " index (SEQNO))");
00235 }
00236
00237
00238
00239 void PhotonStatSummarizer::LoadDataFromDB( VldContext vldPoint )
00240 {
00241 fDriftTable.NewQuery(vldPoint,fWhichEnd);
00242 MSG("PmtDrift",Msg::kInfo) << "Loaded " << vldPoint.AsString() << " end = " << fWhichEnd << " rows = " << fDriftTable.GetNumRows() << endl;
00243
00244 fSpots.clear();
00245
00246 PlexHandle plex(vldPoint);
00247
00248 for(UInt_t i=0;i<fDriftTable.GetNumRows();i++) {
00249 const PulserDrift* row = fDriftTable.GetRow(i);
00250 if(row) {
00251 PlexStripEndId seid =
00252 PlexStripEndId::UnbuildPlnStripEndKey(vldPoint.GetDetector(),
00253 row->GetStripEnd()
00254 );
00255
00256 PlexPixelSpotId psid = plex.GetPixelSpotId(seid);
00257
00258
00259
00260 if(psid.IsValid()) {
00261 SpotDrift& s = fSpots[psid];
00262 if(s.n != 0) MSG("PmtDrift",Msg::kWarning) << "Conflict! Two strips with psid " << psid.AsString() << " " << seid.AsString() << endl;
00263 s.seid = seid;
00264 s.psid = psid;
00265 s.rcid = plex.GetRawChannelId(seid);
00266 s.crate = s.rcid.GetCrate();
00267 s.geo = s.rcid.GetGeographicAddress();
00268 s.masterch = s.rcid.GetMasterChannel();
00269 s.minderch = s.rcid.GetMinderChannel();
00270 s.varc = s.rcid.GetVarcId();
00271 s.vmm = s.rcid.GetVmm();
00272 s.vfb = s.rcid.GetVaAdcSel();
00273 s.vachip = s.rcid.GetVaChip();
00274 s.vachan = s.rcid.GetVaChannel();
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 s.n = row->GetNumEntries();
00286 s.nflash = row->GetNumTriggers();
00287 s.mean = FloatErr(row->GetMean(),row->GetError());
00288 float err = row->GetError();
00289 s.rms2 = err*err*s.n;
00290 if(s.n>0)
00291 s.rms2.SetError(sqrt(2.0)*s.rms2.GetValue()/sqrt(s.n));
00292 else
00293 s.rms2.SetError(s.rms2.GetValue() * 1e9);
00294
00295 const FloatErr k1PeWidthCorr(1.0/1.2,0);
00296
00297
00298 s.gain = (s.rms2/s.mean)*k1PeWidthCorr;
00299
00300
00301 if(s.mean<150) {
00302 FloatErr corrMean = s.mean*s.n/s.nflash;
00303 FloatErr corrRms2 = s.rms2;
00304 s.gain = corrRms2/corrMean * k1PeWidthCorr;
00305 }
00306
00307 if(psid.GetElecType()==ElecType::kVA) {
00308
00309 s.bad = 0;
00310
00311
00312 if(s.mean<150.) s.bad = 1;
00313 if(s.mean>9000.) s.bad = 2;
00314 } else {
00315
00316 s.bad = 0;
00317
00318
00319 if(s.mean<250.) s.bad = 1;
00320 if(s.mean>15000.) s.bad = 2;
00321 if(s.gain>400.) s.bad = 3;
00322 }
00323
00324
00325 }
00326 }
00327 }
00328 MSG("PmtDrift",Msg::kInfo) << "Found " << fSpots.size() << " spots." << endl;
00329 }
00330
00331
00332
00333
00334 void PhotonStatSummarizer::ComputePmtDrifts()
00335 {
00337
00338 fPmts.clear();
00339
00340 SpotList_t::iterator it;
00341 SpotList_t::iterator end= fSpots.end();
00342
00343 for(it = fSpots.begin(); it!=end; it++) {
00344 PlexPixelSpotId pmt = it->first;
00345 FloatErr spotGain = it->second.gain;
00346
00347
00348 PmtDrift& d = fPmts[pmt.GetUniquePmtEncodedValue()];
00349 d.pmt = pmt;
00350
00351 if(d.nspot>127) {
00352 MSG("PmtDrift",Msg::kError) << "Found too many spots. " << it->first.AsString() << endl;
00353 } else {
00354 d.spots[d.nspot] = it->second;
00355 d.nspot += 1;
00356 }
00357 if(spotGain > d.highestGain) d.highestGain = spotGain;
00358 if(spotGain < d.lowestGain) d.lowestGain = spotGain;
00359 d.rcid = it->second.rcid;
00360
00361
00362
00363 }
00364
00366
00367
00368 PmtList_t::iterator pit;
00369 PmtList_t::iterator pend = fPmts.end();
00370
00371 for(pit = fPmts.begin(); pit!=pend; pit++) {
00372 PmtDrift& d = pit->second;
00373
00374 PlexPixelSpotId pmt = d.pmt;
00375 d.pmt.SetPixel(127);
00376 d.pmt.SetSpot(15);
00377 d.encoded = pmt.GetEncoded();
00378 d.side = pmt.GetEastWest();
00379 d.level = pmt.GetRackLevel();
00380 d.bay = pmt.GetRackBay();
00381 d.muxbox = pmt.GetInRack();
00382 d.tube = pmt.GetTube();
00383
00384
00385 d.rawGain = 0;
00386 for(int i=0;i<d.nspot;i++) d.rawGain += d.spots[i].gain/FloatErr(d.nspot);
00387
00388 int big = 0;
00389 for(int i=0;i<d.nspot;i++) if(d.spots[i].gain > d.spots[big].gain) { big=i; };
00390 d.spots[big].bad=3;
00391
00392
00393 std::sort(d.spots.begin(),d.spots.begin() + d.nspot);
00394
00395
00396 d.ngood = 0;
00397 d.nbadLow = d.nbadHigh = 0;
00398
00399 for(Int_t i=0;i<d.nspot;i++) {
00400 if(d.spots[i].bad ==0) d.ngood++;
00401 else if(d.spots[i].bad ==1) d.nbadLow++;
00402 else if(d.spots[i].bad ==2) d.nbadHigh++;
00403 }
00404
00405
00406
00407 if(d.ngood>0) {
00408
00409
00410 d.meanGain = 0;
00411 for(int i=0;i<d.ngood;i++) d.meanGain+=d.spots[i].gain / FloatErr(d.ngood,0);
00412
00413
00414 d.finalGain = GetWeightedMean(d.spots.begin(), d.spots.begin() + d.ngood);
00415
00416
00417 int worst = d.ngood-1;
00418 if( (d.ngood<d.nspot)
00419
00420 ) {
00421 worst = d.ngood;
00422 }
00423
00424
00425 FloatErr meanWithout(0,0);
00426 FloatErr meanWith(0,0);
00427
00428
00429 for(int i=0;i<worst;i++) meanWithout += d.spots[i].gain / FloatErr(worst);
00430
00431
00432
00433 meanWith = (meanWithout*FloatErr(worst) + d.spots[worst].gain) / FloatErr(worst+1);
00434
00435
00436
00437 d.sysError = fabs(meanWith - meanWithout);
00438
00439 MSG("PmtDrift",Msg::kDebug) << "Pmt " << d.pmt.AsString()
00440 << Form("%3d %3d", d.nspot, d.ngood)
00441 << " \t" << d.finalGain
00442 << " \t" << d.rawGain
00443 << " \t" << d.sysError
00444 << " \t" << d.lowestGain
00445 << " \t" << d.highestGain
00446 << endl;
00447
00448 }
00449 }
00450 }
00451
00452 void PhotonStatSummarizer::ComputeDetectorDrift()
00453 {
00454 fDetectorDrift.Reset();
00455
00456 double tot = 0;
00457 double tot2 = 0;
00458 double n = 0;
00459
00460
00461 SpotList_t::iterator it;
00462 SpotList_t::iterator end= fSpots.end();
00463 for(it = fSpots.begin(); it!=end; it++) {
00464 double g = it->second.gain;
00465 tot += g;
00466 tot2 += g*g;
00467 n+=1.0;
00468 }
00469 if(n>2) {
00470 fDetectorDrift.meanSpotGain = tot/n;
00471 fDetectorDrift. rmsSpotGain = sqrt(fabs(tot2 - tot*tot/n)/(n-1));
00472 }
00473 fDetectorDrift.numSpots = n;
00474
00475
00476
00477 tot=tot2=n=0;
00478 double stots[8];
00479 double sn[8];
00480 for(UInt_t i=0;i<8;i++) { stots[i] = sn[i] = 0; };
00481
00482 PmtList_t::iterator pit;
00483 PmtList_t::iterator pend = fPmts.end();
00484 for(pit = fPmts.begin(); pit!=pend; pit++) {
00485 PlexPixelSpotId psid = pit->second.pmt;
00486 int section = 0;
00487 if(psid.GetEastWest()!='E') section+=1;
00488 if(psid.GetRackLevel()!='L') section+=2;
00489 if(psid.GetRackBay()>8) section+=4;
00490
00491 double g = pit->second.finalGain;
00492 tot += g;
00493 tot2+= g*g;
00494 n+=1;
00495 if(g<fDetectorDrift.lowestPmt) fDetectorDrift.lowestPmt = g;
00496 if(g>fDetectorDrift.highestPmt) fDetectorDrift.highestPmt = g;
00497 stots[section] +=g;
00498 sn[section] += 1.0;
00499 }
00500
00501 if(n>2) {
00502 fDetectorDrift.meanPmtGain = tot/n;
00503 fDetectorDrift. rmsPmtGain = sqrt(fabs(tot2 - tot*tot/n)/(n-1));
00504 }
00505 fDetectorDrift.numPmts = n;
00506 for(UInt_t i=0;i<8;i++) {
00507 if(sn[i]>0) fDetectorDrift.section[i] = stots[i]/sn[i];
00508 };
00509
00510 }
00511
00512
00513 void PhotonStatSummarizer::FillPmtDatabase(Int_t version,
00514 VldContext vldPointStart,
00515 Int_t task)
00516 {
00517 if(fPmts.size() == 0) {
00518 MSG("PmtDrift",Msg::kWarning) << "No PMTs to fill into DB. " << vldPointStart.AsString() << endl;
00519 }
00520 VldTimeStamp creationTime = vldPointStart.GetTimeStamp() + VldTimeStamp(version,0);
00521 VldTimeStamp beginTime = vldPointStart.GetTimeStamp();
00522 VldTimeStamp endTime = beginTime + VldTimeStamp(3600*24,0);
00523 VldRange range(vldPointStart.GetDetector(),
00524 vldPointStart.GetSimFlag(),
00525 beginTime,
00526 endTime,
00527 "PhotonStatSummarizer::Summarize" );
00528
00529
00530 int ncrates = 16;
00531 if(vldPointStart.GetDetector()==Detector::kNear) ncrates = 8;
00532
00533 int crates_with_data = 0;
00534 int rows_total = 0;
00535
00536 for(int crate = 0; crate< ncrates; crate++) {
00537
00538 DbiWriter<CalPmtDrift> writer(range,
00539 crate,
00540 task,
00541 creationTime,
00542 0,
00543 Form("Code version %d. Created by %s",
00544 version,
00545 "$Id: PhotonStatSummarizer.cxx,v 1.25 2006/05/27 10:05:44 rhatcher Exp $")
00546 );
00547
00548 PmtList_t::iterator pit;
00549 PmtList_t::iterator pend = fPmts.end();
00550 Int_t nrows = 0;
00551
00552 for(pit = fPmts.begin(); pit!=pend; pit++) {
00553 PmtDrift& d = pit->second;
00554
00555 if(d.rcid.GetCrate()==crate) {
00556 CalPmtDrift cpd(d.pmt,
00557 d.rcid,
00558 d.finalGain.GetValue(),
00559 d.finalGain.GetError(),
00560 d.sysError,
00561 d.ngood,
00562 d.nspot,
00563 d.rawGain,
00564 d.lowestGain,
00565 d.highestGain);
00566
00567 writer << cpd;
00568 nrows++;
00569 }
00570 }
00571
00572
00573 if(nrows>0){
00574 writer.Close();
00575 crates_with_data++;
00576 rows_total += nrows;
00577 }
00578 }
00579
00580 MSG("PmtDrift",Msg::kInfo) << "Wrote " << rows_total << " rows to DB from "
00581 << fPmts.size() << " PMTs, in " << crates_with_data << " aggregates" << endl;
00582 }
00583
00584
00585 bool PhotonStatSummarizer::DoesTableExist( Int_t version,
00586 VldContext vldPointStart,
00587 Int_t task )
00588 {
00589
00590
00591
00592
00593
00594
00595 VldTimeStamp creationTime = vldPointStart.GetTimeStamp() + VldTimeStamp(version,0);
00596
00597 const char* sqltxt = Form("(CREATIONDATE='%s') and (TASK=%d) and (DETECTORMASK & %d) and (SIMMASK & %d) order by TIMESTART asc limit 1",
00598 creationTime.AsString("s"),
00599 task,
00600 vldPointStart.GetDetector(),
00601 vldPointStart.GetSimFlag() );
00602
00603 DbiSqlContext myContext(sqltxt);
00604
00605 DbiResultPtr<CalPmtDrift> resPtr("CALPMTDRIFT",myContext);
00606 VldTimeStamp ts= resPtr.GetValidityRec()->GetVldRange().GetTimeStart();
00607
00608 if(ts == vldPointStart.GetTimeStamp()) {
00609
00610 if(resPtr.GetNumRows()==0) {
00611 MSG("PmtDrift",Msg::kWarning) << "..Found existing table version " << version << " but no data. Treating as empty." << endl;
00612 return false;
00613 }
00614
00615 return true;
00616 }
00617 return false;
00618 }
00619
00620
00621 void PhotonStatSummarizer::FillTrees( VldContext vldPoint )
00622 {
00623 static DetectorDrift* det_ptr = 0;
00624 static PmtDrift* pmt_ptr =0;
00625 static SpotDrift* spot_ptr =0;
00626 static VldContext* cx_ptr = 0;
00627 static Float_t* temp_ptr = 0;
00628 static Float_t temp;
00629
00630 if(fFile==0) {
00631 fFile = new TFile(GetConfig().GetCharString("FileName"),"RECREATE");
00632 fDetTree = (TTree*) fFile->Get("det");
00633 fPmtTree = (TTree*) fFile->Get("pmts");
00634 fSpotTree = (TTree*) fFile->Get("spots");
00635 }
00636
00637 cx_ptr = &vldPoint;
00638 temp_ptr = &temp;
00639 Calibrator::Instance().Reset(vldPoint);
00640 temp = Calibrator::Instance().GetTemperature();
00641 cout << vldPoint.AsString() << " Temp = " << temp << endl;
00642
00643 if(fWriteDetTree) {
00644 if(fPmtTree==0) {
00645 fDetTree = new TTree("det","det");
00646 fDetTree->Branch("det_br","DetectorDrift",&det_ptr,32000,3);
00647 fDetTree->Branch("cx_br","VldContext",&cx_ptr,32000,3);
00648 fDetTree->Branch("temp_br",temp_ptr,"T/F",32000);
00649 } else {
00650 fDetTree->SetBranchAddress("det_br",&det_ptr);
00651 fDetTree->SetBranchAddress("cx_br",&cx_ptr);
00652 fDetTree->SetBranchAddress("temp_br",temp_ptr);
00653 }
00654 det_ptr = &fDetectorDrift;
00655 fDetTree->Fill();
00656 fDetTree->AutoSave();
00657 }
00658
00659
00660 if(fWritePmtTree) {
00661 if(fPmtTree==0) {
00662 fPmtTree = new TTree("pmts","pmts");
00663 fPmtTree->Branch("pmt_br","PmtDrift",&pmt_ptr,32000,3);
00664 fPmtTree->Branch("cx_br","VldContext",&cx_ptr,32000,3);
00665 fPmtTree->Branch("temp_br",temp_ptr,"T/F",32000);
00666 } else {
00667 fPmtTree->SetBranchAddress("pmt_br",&pmt_ptr);
00668 fPmtTree->SetBranchAddress("cx_br",&cx_ptr);
00669 fPmtTree->SetBranchAddress("temp_br",temp_ptr);
00670 }
00671
00672 PmtList_t::iterator pit;
00673 PmtList_t::iterator pend = fPmts.end();
00674 for(pit = fPmts.begin(); pit!=pend; pit++) {
00675 pmt_ptr = &(pit->second);
00676 fPmtTree->Fill();
00677 }
00678 fPmtTree->AutoSave();
00679 }
00680
00681 if(fWriteSpotTree) {
00682 if(fSpotTree==0) {
00683 fSpotTree = new TTree("spots","spots");
00684 fSpotTree->Branch("spot_br","SpotDrift",&spot_ptr,32000,3);
00685 fSpotTree->Branch("cx_br","VldContext",&cx_ptr,32000,3);
00686 fSpotTree->Branch("temp_br",temp_ptr,"T/F",32000);
00687 } else {
00688 fSpotTree->SetBranchAddress("spot_br",&spot_ptr);
00689 fSpotTree->SetBranchAddress("cx_br",&cx_ptr);
00690 fSpotTree->SetBranchAddress("temp_br",temp_ptr);
00691 }
00692
00693 SpotList_t::iterator it;
00694 SpotList_t::iterator end= fSpots.end();
00695
00696 for(it = fSpots.begin(); it!=end; it++) {
00697 spot_ptr = &(it->second);
00698 fSpotTree->Fill();
00699 }
00700 fSpotTree->AutoSave();
00701 }
00702 }