14 #include "CSMStatusUtils.h"
21 #include "TIterator.h"
27 #include "tables/St_emcStatus_Table.h"
28 #include "tables/St_emcPed_Table.h"
29 #include "StEmcUtil/database/StEmcDecoder.h"
41 typedef map<Int_t,vector<Short_t>*>::const_iterator IntToPtrVecShortConstIter ;
45 CSMStatusUtils::setDetectorFlavor(TString flavor) {
46 mDetectorFlavor=flavor;
47 if(mDetectorFlavor==
"bemc") {
49 mDetectorActualSize=4800;
50 mRunStatusMapPtr=&mBEMCRunStatusMap;
51 }
else if(mDetectorFlavor==
"eemc") {
53 mDetectorActualSize=720;
54 mRunStatusMapPtr=&mEEMCRunStatusMap;
56 ifstream ifs(
"StRoot/StEmcPool/CSMStatusUtils/eemccratemap");
57 int tower, crate, channel;
60 sscanf(tms.Data(),
"%d %d %d",&crate,&channel,&tower);
61 eemcCrateMap[crate-1][channel] = tower;
71 CSMStatusUtils::initializeHistFileFromDir(TString directory,TString filter) {
74 if ((dir = gSystem->OpenDirectory(directory.Data())) != NULL) {
75 const Char_t *dirEntry;
76 while ((dirEntry = gSystem->GetDirEntry(dir)) != NULL) {
78 strcpy(buffer,directory.Data());
79 if (buffer[strlen(buffer)-1] !=
'/') strcat(buffer,
"/");
80 strcat(buffer,dirEntry);
81 if (!strstr(buffer,filter.Data()))
continue;
82 Char_t* needle = strstr(buffer,
"run");
87 strncpy(runString,needle,7);
88 runNumber = atoi(runString);
90 if (runNumber != 0) mHistFileMap[runNumber] = buffer;
93 return mHistFileMap.size();
100 CSMStatusUtils::readTablesFromASCII(TString directory,TString filter) {
102 TString buffert = directory +
"/status/";
104 if ((dir = gSystem->OpenDirectory(buffert.Data())) != NULL) {
105 const Char_t *dirEntry;
106 while ((dirEntry = gSystem->GetDirEntry(dir)) != NULL) {
108 strcpy(buffer,buffert.Data());
109 strcat(buffer,dirEntry);
110 if (!strstr(buffer,filter.Data()))
continue;
112 if(!tmpstr.Contains(mDetectorFlavor.Data()))
continue;
113 Char_t* needle = strstr(buffer,
"run");
114 Int_t runNumber = 0, thetime = 0, thedate = 0;
117 Char_t runString[10];
118 Char_t timeString[10];
119 Char_t dateString[10];
120 strncpy(runString,needle,7);
121 runNumber = atoi(runString);
123 strncpy(dateString,needle,8);
124 thedate = atoi(dateString);
126 strncpy(timeString,needle,6);
127 thetime = atoi(timeString);
129 if (runNumber != 0) {
133 vector<Short_t>* vec =
new vector<Short_t>(mDetectorSize+1);
134 for(
int id=1;
id<mDetectorSize+1;
id++) {
136 in >> itemp >> status;
140 cout << buffer <<
" is status file that was read" << endl;
141 (*mRunStatusMapPtr)[runNumber] = vec;
142 mRunTimestampMap[runNumber] = thetime;
143 mRunDatestampMap[runNumber] = thedate;
151 return mRunStatusMapPtr->size();
155 CSMStatusUtils::plotAllStatuses(TString rootfiledir,
int year,
int runstart) {
158 vector<Int_t> runlist;
160 if ((dir = gSystem->OpenDirectory(rootfiledir.Data())) != NULL) {
161 const Char_t *dirEntry;
162 while ((dirEntry = gSystem->GetDirEntry(dir)) != NULL) {
164 strcpy(buffer,rootfiledir.Data());
165 strcat(buffer,dirEntry);
166 if (!strstr(buffer,
".root"))
continue;
167 if (strstr(buffer,
"run.root"))
continue;
168 Char_t* needle = strstr(buffer,
"run");
172 Char_t runString[10];
173 strncpy(runString,needle,7);
174 runNumber = atoi(runString);
175 runlist.push_back(runNumber);
180 ptm.tm_year = year-1900;
181 int firstdate=99999999, firsttime,lastdate=0, lasttime, firstrun=99999999, lastrun=0;
182 IntToPtrVecShortConstIter first = mRunStatusMapPtr->begin();
183 IntToPtrVecShortConstIter last = mRunStatusMapPtr->end();
184 IntToPtrVecShortConstIter iter = first;
185 for(iter=first;iter!=last;iter++) {
186 runnumber = iter->first;
187 if(runnumber < runstart)
continue;
188 if(firstdate > mRunDatestampMap[runnumber]) {
189 firstdate = mRunDatestampMap[runnumber];
190 firsttime = mRunTimestampMap[runnumber];
191 }
else if (firstdate == mRunDatestampMap[runnumber] && firsttime > mRunTimestampMap[runnumber]) {
192 firsttime = mRunTimestampMap[runnumber];
194 if(lastdate < mRunDatestampMap[runnumber]) {
195 lastdate = mRunDatestampMap[runnumber];
196 lasttime = mRunTimestampMap[runnumber];
197 }
else if (lastdate == mRunDatestampMap[runnumber] && lasttime < mRunTimestampMap[runnumber]) {
198 lasttime = mRunTimestampMap[runnumber];
200 if(firstrun > runnumber && runnumber > runstart) firstrun = runnumber;
201 if(lastrun < runnumber) lastrun = runnumber;
204 int bigyearnumber = year*10000;
206 ptm.tm_mon = ((firstdate-bigyearnumber)/100)+1;
207 ptm.tm_mday = (firstdate-bigyearnumber)%100;
208 ptm.tm_hour = firsttime/10000;
209 ptm.tm_min = (firsttime%10000)/100;
210 ptm.tm_sec = firsttime%100;
211 time_t firstdatet = mktime(&ptm);
212 ptm.tm_mon = ((lastdate-bigyearnumber)/100)+1;
213 ptm.tm_mday = (lastdate-bigyearnumber)%100;
214 ptm.tm_hour = lasttime/10000;
215 ptm.tm_min = (lasttime%10000)/100;
216 ptm.tm_sec = lasttime%100;
217 time_t lastdatet = mktime(&ptm);
219 int diffseconds = (int)difftime(lastdatet,firstdatet);
220 TCanvas* tc =
new TCanvas(
"peter",
"Status vs Run Number",800,800);
224 TH2F* histogram =
new TH2F(
"stevegeech",
"Time (Hours) vs BEMC Channels (bad)",4801,-0.5,4800.5,diffseconds/timegap+1,-0.5,diffseconds/timegap+0.5);
239 vector<int> binbounds;
241 for(iter=first;iter!=last;iter++) {
242 runnumber = iter->first;
243 if(runnumber < runstart)
continue;
244 vector<Short_t>* statusVector = (*mRunStatusMapPtr)[runnumber];
246 ptm.tm_mon = ((mRunDatestampMap[runnumber]-bigyearnumber)/100)+1;
247 ptm.tm_mday = (mRunDatestampMap[runnumber]-bigyearnumber)%100;
248 ptm.tm_hour = mRunTimestampMap[runnumber]/10000;
249 ptm.tm_min = (mRunTimestampMap[runnumber]%10000)/100;
250 ptm.tm_sec = mRunTimestampMap[runnumber]%100;
251 time_t timet = mktime(&ptm);
252 double timedifference = difftime(timet,firstdatet);
253 int ratiodifftogap = (int)timedifference/timegap;
254 currentbin = histogram->GetBin(0,ratiodifftogap)/(mDetectorSize+3);
256 binbounds.push_back(currentbin);
259 binbounds.push_back(currentbin);
261 for(iter=first;iter!=last;iter++) {
262 runnumber = iter->first;
263 if(runnumber < runstart)
continue;
264 vector<Short_t>* statusVector = (*mRunStatusMapPtr)[runnumber];
275 for(
int i=1; i<4801; i++) {
276 if((*statusVector)[i]!=1) {
277 for(
int bound=binbounds[bb]; bound<binbounds[bb+1]; bound++) {
278 histogram->Fill(i,bound);
287 histogram->Draw(
"colz");
297 CSMStatusUtils::saveAbbreviatedStatusTablesToASCII(TString directory) {
301 IntToPtrVecShortConstIter first = mRunStatusMapPtr->begin();
302 IntToPtrVecShortConstIter last = mRunStatusMapPtr->end();
303 IntToPtrVecShortConstIter iter = first;
304 IntToPtrVecShortConstIter preiter = first;
314 vector<Float_t> statuscounter(mDetectorSize+1);
315 vector<Short_t> totalStatusVector(mDetectorSize+1);
316 for(
int i=0; i<mDetectorSize+1; i++) {
317 totalStatusVector[i] = 1;
318 statuscounter[i] = 0;
320 Short_t fakeZero = 1024;
321 Bool_t firstone = kTRUE;
322 Short_t oldstatus, status;
323 Int_t badChannelsInRun;
324 for(iter=first;iter!=last;iter++) {
325 runnumber = iter->first;
326 vector<Short_t>* statusVector = iter->second;
327 vector<Short_t>* oldStatusVector = preiter->second;
328 badChannelsInRun = 0;
329 for (Int_t i = 1; i < mDetectorSize + 1; i++) {
330 oldstatus = (*oldStatusVector)[i];
331 status = (*statusVector)[i];
332 if(oldstatus == 0) oldstatus = fakeZero;
333 if(status == 0) status = fakeZero;
341 totalStatusVector[i] = status;
342 }
else if(oldstatus == 1 && status == 1) {
344 }
else if(status != 1) {
345 if(totalStatusVector[i] == 1) {
346 totalStatusVector[i] = status;
348 totalStatusVector[i] |= status;
350 }
else if(oldstatus != 1) {
351 if(totalStatusVector[i] == 1) {
352 totalStatusVector[i] = oldstatus;
354 totalStatusVector[i] |= oldstatus;
357 if(totalStatusVector[i] == 1) {
358 totalStatusVector[i] = (oldstatus | status);
360 totalStatusVector[i] |= (oldstatus | status);
366 if(i < mDetectorActualSize) badChannelsInRun++;
369 if (oldstatus != status) statuscounter[i] += 1;
372 for (Int_t i = 1; i < mDetectorSize + 1; i++) {
373 oldstatus = (*oldStatusVector)[i];
374 status = (*statusVector)[i];
375 if(badChannelsInRun > 0.5 * mDetectorActualSize && oldstatus != status)
376 statuscounter[i] -= 1;
385 TString datetimestring, runnumberstring;
387 for(iter=first; iter!=last; iter++) {
388 int numberofchangedchannels=0;
389 runnumber = iter->first;
390 runnumberstring =
"";
391 runnumberstring += runnumber;
392 tmpstr = directory +
"/status/short_status_" + mDetectorFlavor +
"_run"
393 + runnumberstring +
".status";
394 ofstream ofs(tmpstr.Data());
396 St_emcStatus *bemc_status=
new St_emcStatus(
"bemcStatus",1);
397 emcStatus_st *emcstatus=bemc_status->GetTable();
398 for (Int_t i_tow=0; i_tow<4800; i_tow++) emcstatus->Status[i_tow]=1;
400 vector<Short_t>* statusVector = iter->second;
401 vector<Short_t>* oldStatusVector = preiter->second;
402 for (UInt_t i = 1; i < statusVector->size(); i++) {
403 oldstatus = (*oldStatusVector)[i];
404 status = (*statusVector)[i];
407 if ( firstone && (statuscounter[i]/mRunStatusMapPtr->size() > 0.1 ) && mRunStatusMapPtr->size() > 3) {
410 cout <<
"statcou is " << statuscounter[i] <<
" for channel " << i <<
" and size is " << mRunStatusMapPtr->size() << endl;
411 if(totalStatusVector[i] & fakeZero) ofs << i <<
"\t" <<
"0" << endl;
412 else ofs << i <<
"\t" << totalStatusVector[i] << endl;
415 }
else if (firstone ||
416 (oldstatus != status && (statuscounter[i]/mRunStatusMapPtr->size() <= 0.1 || mRunStatusMapPtr->size() <= 10))) {
417 ofs << i <<
"\t" << status << endl;
418 numberofchangedchannels++;
427 emcstatus->Status[i-1]=status;
429 ofs << numberofchangedchannels <<
" channels changed" << endl;
431 datetimestring = getDateTimeString(runnumber);
432 TString statusrootfilename =
433 directory +
"/status/" + mDetectorFlavor +
"Status" + datetimestring +
"root";
434 TFile* fout_status =
new TFile(statusrootfilename.Data(),
"RECREATE");
436 bemc_status->AddAt(emcstatus,0);
437 bemc_status->Write();
438 fout_status->Close();
492 gStyle->SetOptStat(0);
493 gStyle->SetOptTitle(0);
495 tmpstr = mDetectorFlavor +
"StatusPlots";
496 TCanvas *c1 =
new TCanvas(tmpstr.Data(),tmpstr.Data());
499 TCanvas *c2 =
new TCanvas(
"towerAdcPlots",
"towerAdcPlots",400,400);
504 tmpstr = plotDir + mDetectorFlavor +
"Status.html";
505 cout <<
"htmlSummary: " << tmpstr << endl;
506 ofstream htmlSummary(tmpstr.Data());
507 if (!htmlSummary) cout <<
"htmlSummary isn't defined!" << endl;
508 writeHtmlHeaderSummary(htmlSummary);
515 TH2F* priorHist = NULL;
516 TH2F* currentHist = NULL;
517 TH2F* tmpHist = NULL;
518 TString runnumberstring;
519 int runnumber, priorRunNumber, currentRunNumber=99999999, savedCurrentRunNumber;
520 int priorTimeStamp, currentTimeStamp=99999999;
521 int priorDateStamp, currentDateStamp=99999999;
522 Bool_t firstGoodRun = kTRUE;
523 Float_t averageNumberHitsPerChan;
526 std::vector<Short_t>* statusVector;
527 std::vector<Float_t>* pedestalmean;
528 std::vector<Float_t>* pedestalwidth;
529 std::vector<Float_t>* pedestalchi;
531 Int_t hottowerPlotNameIter = -1;
532 ofstream outputlog(
"MOSTRECENTLOG.txt");
534 for (map<Int_t,string>::const_iterator iter = mHistFileMap.begin();
535 iter != mHistFileMap.end(); ++iter) {
537 TFile* file =
new TFile(iter->second.c_str(),
"READ");
538 outputlog <<
"doing file " << iter->second.c_str() << endl;
539 cout <<
"doing file " << iter->second.c_str() << endl;
540 if (file && file->IsOpen()) {
541 outputlog <<
" it opened" << endl;
542 cout <<
" it opened" << endl;
543 runnumber = iter->first;
545 runnumberstring =
"";
546 runnumberstring += runnumber;
547 hottowerPlotNameIter++;
548 tmpstr = mDetectorFlavor +
"StatusAdc_" + runnumberstring;
549 TH2F* runHist =
dynamic_cast<TH2F*
>(file->Get(tmpstr.Data()));
550 TTree* myTree =
dynamic_cast<TTree*
>(file->Get(
"calinfo"));
557 outputlog <<
"it's the first good run" << endl;
558 cout <<
"it's the first good run" << endl;
559 currentHist =
dynamic_cast<TH2F*
>(runHist->Clone(
"ch1"));
560 currentHist->SetDirectory(0);
561 priorHist =
dynamic_cast<TH2F*
>(runHist->Clone(
"ph1"));
562 priorHist->SetDirectory(0);
564 firstGoodRun = kFALSE;
566 currentHist->Add(runHist);
569 setDateTimeInfo(runnumber,myTree);
573 myTree->SetBranchAddress(
"fillnum",&runFillNum);
577 cout<<
"runfillnumb is " << runFillNum << endl;
582 if(runnumber < currentRunNumber) currentRunNumber = runnumber;
583 runnumberstring =
"";
584 runnumberstring += currentRunNumber;
585 savedCurrentRunNumber = currentRunNumber;
586 if(mRunDatestampMap[runnumber] < currentDateStamp) {
587 currentDateStamp = mRunDatestampMap[runnumber];
588 currentTimeStamp = mRunTimestampMap[runnumber];
589 }
else if(mRunDatestampMap[runnumber] == currentDateStamp &&
590 mRunTimestampMap[runnumber] < currentTimeStamp) {
591 currentTimeStamp = mRunTimestampMap[runnumber];
596 statusVector =
new vector<Short_t>(mDetectorSize+1);
597 pedestalmean =
new vector<Float_t>(mDetectorSize+1);
598 pedestalwidth =
new vector<Float_t>(mDetectorSize+1);
599 pedestalchi =
new vector<Float_t>(mDetectorSize+1);
602 tmpstr += hottowerPlotNameIter;
604 hHotTower =
new TH1F(tmpstr.Data(),
"# of tower hits",mDetectorSize+1,-0.5,mDetectorSize+1-0.5);
605 hHotTower->GetXaxis()->SetTitle(
"Tower Id");
606 hHotTower->GetYaxis()->SetTitle(
"Number of Hits Above Pedestal");
610 goodTowers = analyseStatusHistogram(currentHist,plotDir,averageNumberHitsPerChan,
611 currentDateStamp,currentTimeStamp,
612 *statusVector,*pedestalmean,*pedestalwidth,*pedestalchi,hHotTower);
614 if(averageNumberHitsPerChan > 100) {
616 outputlog <<
" good statistics!" << endl;
617 cout <<
" good statistics!" << endl << endl;
621 priorHist = currentHist;
622 currentHist = tmpHist;
623 priorTimeStamp = currentTimeStamp;
624 currentTimeStamp = 99999999;
625 priorDateStamp = currentDateStamp;
626 currentDateStamp = 99999999;
627 priorRunNumber = currentRunNumber;
628 currentRunNumber = 99999999;
630 }
else if(mFillEndMap[runnumber]) {
631 outputlog <<
"end of fill and poor statistics! average: " << averageNumberHitsPerChan << endl;
632 cout <<
"end of fill and poor statistics! average: " << averageNumberHitsPerChan << endl << endl;
633 currentHist->Add(priorHist);
634 if(priorRunNumber < currentRunNumber) currentRunNumber = priorRunNumber;
635 runnumberstring =
"";
636 runnumberstring += currentRunNumber;
637 savedCurrentRunNumber = currentRunNumber;
638 if(priorDateStamp < currentDateStamp) {
639 currentDateStamp = priorDateStamp;
640 currentTimeStamp = priorTimeStamp;
641 }
else if(priorDateStamp == currentDateStamp &&
642 priorTimeStamp < currentTimeStamp) {
643 currentTimeStamp = priorTimeStamp;
647 delete pedestalwidth;
649 statusVector =
new vector<Short_t>(mDetectorSize+1);
650 pedestalmean =
new vector<Float_t>(mDetectorSize+1);
651 pedestalwidth =
new vector<Float_t>(mDetectorSize+1);
652 pedestalchi =
new vector<Float_t>(mDetectorSize+1);
654 hHotTower->GetXaxis()->SetTitle(
"Tower Id");
655 hHotTower->GetYaxis()->SetTitle(
"Number of Hits Above Pedestal");
656 goodTowers = analyseStatusHistogram(currentHist,plotDir,averageNumberHitsPerChan,
657 currentDateStamp,currentTimeStamp,
658 *statusVector,*pedestalmean,*pedestalwidth,*pedestalchi,hHotTower);
659 if(averageNumberHitsPerChan < 50) {
660 outputlog <<
" fill has ended and stats suck! Number is " << averageNumberHitsPerChan << endl;
661 cout <<
" fill has ended and stats suck! Number is " << averageNumberHitsPerChan << endl << endl;
663 currentHist->Reset();
664 priorTimeStamp = 99999999;
665 currentTimeStamp = 99999999;
666 priorDateStamp = 99999999;
667 currentDateStamp = 99999999;
668 priorRunNumber = 99999999;
669 currentRunNumber = 99999999;
672 delete pedestalwidth;
680 outputlog <<
" poor statistics! average: " << averageNumberHitsPerChan << endl;
681 cout <<
" poor statistics! average: " << averageNumberHitsPerChan << endl;
684 delete pedestalwidth;
692 if(mFillEndMap[runnumber]) {
693 outputlog <<
" fill has ended!" << endl;
694 cout <<
" fill has ended!" << endl << endl;
697 currentHist->Reset();
698 priorTimeStamp = 99999999;
699 currentTimeStamp = 99999999;
700 priorDateStamp = 99999999;
701 currentDateStamp = 99999999;
702 priorRunNumber = 99999999;
703 currentRunNumber = 99999999;
707 cout <<
"Got here? 1 " << endl;
728 (*mRunStatusMapPtr)[savedCurrentRunNumber] = statusVector;
730 writePedestals(savedCurrentRunNumber,plotDir,*statusVector,*pedestalmean,*pedestalwidth,*pedestalchi);
733 tmpstr = plotDir +
"/status/";
734 saveStatusTablesToASCII(tmpstr.Data(), savedCurrentRunNumber);
736 gStyle->SetOptStat(1111);
740 tmpstr = plotDir +
"/run" + runnumberstring +
"_" + mDetectorFlavor +
"_hotTowers.gif";
741 if(gROOT->IsBatch()) {
742 tmpstr = plotDir +
"/run" + runnumberstring +
"_" + mDetectorFlavor +
"_hotTowers.eps";
744 c1->SaveAs(tmpstr.Data());
747 htmlSummary <<
"<tr>" << endl
748 <<
"<td>" <<
"Fill " << runFillNum <<
"</td>" <<
", " << endl
749 <<
"<td> " <<
"Run " << savedCurrentRunNumber <<
" </td> " << endl
750 <<
"<td> " << goodTowers <<
" good towers" <<
" </td>" << endl
751 <<
"<td> " << getNumberOfChangedTowers(savedCurrentRunNumber) <<
" towers changed from previous run"
754 tmpstr =
"./run" + runnumberstring +
"_" + mDetectorFlavor +
"_badTowers.html";
755 htmlSummary <<
"<td> <a href=\"" << tmpstr.Data() <<
"\"> list </a></td><br>"
760 tmpstr = plotDir +
"/run" + runnumberstring +
"_" + mDetectorFlavor +
"_badTowers.html";
761 ofstream htmlout(tmpstr.Data());
762 writeHtmlHeaderBadTowerList(htmlout,savedCurrentRunNumber);
769 for (Int_t i=1; i<=mDetectorSize; i++) {
770 if ((*statusVector)[i] != 1 && (*statusVector)[i] != 18 && (*statusVector)[i] != 0) {
772 htmlout <<
"<tr> <td> " << i <<
" </td> <td> "
773 << (*statusVector)[i] <<
" </td> <td> " << endl;
775 IntToPtrVecShortConstIter statusIter;
776 statusIter = mRunStatusMapPtr->find(savedCurrentRunNumber);
778 if (statusIter != mRunStatusMapPtr->begin()) {
779 IntToPtrVecShortConstIter preIter = statusIter;
782 if ((*(statusIter->second))[i] == (*(preIter->second))[i] ||
783 (*(statusIter->second))[i] == 1 ||
784 (*(statusIter->second))[i] == 0) {
785 htmlout <<
"- </td> </tr><br>" << endl;
788 if(getNumberOfChangedTowers(runnumber) > 25) {
790 htmlout <<
"- </td> </tr><br>" << endl;
800 Int_t bin = priorHist->GetXaxis()->FindFixBin(i);
801 TH1D *hTemp = priorHist->ProjectionY(
"projTemp",bin,bin);
804 hTemp->GetXaxis()->SetTitle(
"adc");
805 hTemp->GetXaxis()->SetRange(0,150);
808 sprintf(buffer,
"%s/run%dtower%d_adc.gif",plotDir.Data(),iter->first,i);
810 sprintf(buffer,
"./run%dtower%d_adc.gif",savedCurrentRunNumber,i);
812 htmlout <<
"<a href=\"" << buffer <<
"\" > plot </a>"
813 <<
"</td> </tr>" << endl;
820 IntToPtrVecShortConstIter statusIter;
821 statusIter = mRunStatusMapPtr->find(savedCurrentRunNumber);
822 if (statusIter == mRunStatusMapPtr->begin()) {
824 htmlout <<
"</tbody>" << endl;
825 htmlout <<
"</table>" << endl;
826 htmlout <<
"<br><br> <div>Partial Good Tower List for Comparison</div><br>" << endl;
827 htmlout <<
"<table border=\"1\">" << endl;
828 htmlout <<
"<tbody>" << endl;
829 htmlout <<
"<tr> <th width=\"50\"> Tower ID </th> <th width=\"50\"> Status Code </th> <th width=\"100\"> ADC plot </th> </tr>" << endl;
831 Int_t good_toplot = 1;
832 for (Int_t i=100; i<mDetectorSize && good_toplot<10; i = i+100) {
833 if ((*statusVector)[i] == 1) {
834 htmlout <<
"<tr> <td> " << i <<
" </td> <td> "
835 << (*statusVector)[i] <<
" </td> <td> " << endl;
839 Int_t bin = priorHist->GetXaxis()->FindFixBin(i);
840 TH1D *hTemp = priorHist->ProjectionY(
"projTemp",bin,bin);
844 hTemp->GetXaxis()->SetTitle(
"adc");
848 sprintf(buffer,
"%s/run%dtower%d_adc.gif",plotDir.Data(),iter->first,i);
850 sprintf(buffer,
"./run%dtower%d_adc.gif",savedCurrentRunNumber,i);
851 htmlout <<
"<a href=\"" << buffer <<
"\" > plot </a>"
852 <<
"</td> </tr>" << endl;
859 writeHtmlFooterSummary(htmlout);
860 htmlSummary <<
"</tr>" << endl;
871 writeHtmlFooterSummary(htmlSummary);
872 TH2F* statusHist = makeStatusVersusTimePlot();
878 statusHist->Draw(
"colz");
879 sprintf(buffer,
"%s/bemcStatusPlot.gif",plotDir.Data());
896 CSMStatusUtils::analyseStatusHistogram(TH2F* hist,
898 Float_t& averageNumberOfHitsPerChannel,
901 std::vector<Short_t>& statusVector,
902 std::vector<Float_t>& pedestalmean,
903 std::vector<Float_t>& pedestalwidth,
904 std::vector<Float_t>& pedestalchi,
909 TString runnumber = hist->GetName();
910 runnumber = runnumber(runnumber.Length()-7,7);
914 if ((dir = gSystem->OpenDirectory(directory)) == NULL)
915 gSystem->MakeDirectory(directory);
917 TF1* gaus =
new TF1(
"gaus",
"gaus");
920 for (vector<Short_t>::iterator iter = statusVector.begin(); iter != statusVector.end(); ++iter)
924 for (Int_t chanId = 1; chanId < mDetectorSize+1; chanId++) {
927 TH1D* proj = hist->ProjectionY(
"projTemp",chanId+1,chanId+1);
933 Float_t maxValue = -1;
935 for (Int_t j = 2; j < proj->GetXaxis()->GetNbins(); j++) {
936 if (proj->GetBinContent(j) > maxValue) {
938 maxValue = proj->GetBinContent(j);
941 Float_t pedMean = proj->GetXaxis()->GetBinCenter(maxBin);
957 gaus->SetParameter(0,maxValue);
958 gaus->SetParameter(1,pedMean);
959 gaus->SetParameter(2,3.5);
965 gaus->SetRange(pedMean-10,pedMean+10);
966 proj->Fit(gaus,
"0RQ");
968 if(hPedMean) hPedMean->Fill(gaus->GetParameter(1));
969 if(hPedWidth) hPedWidth->Fill(gaus->GetParameter(2));
971 pedestalmean[chanId] = gaus->GetParameter(1);
972 pedestalwidth[chanId] = gaus->GetParameter(2);
973 pedestalchi[chanId] = gaus->GetChisquare();
978 if (pedestalwidth[chanId] <= 0.5 || pedestalwidth[chanId] > 2.8) {
980 statusVector[chanId] |= 4+32;
985 if (mDetectorFlavor==
"bemc" && (pedestalmean[chanId] < 4 || pedestalmean[chanId] > 145)) {
986 if (pedestalmean[chanId] > 2.6 && pedestalwidth[chanId] < 1.5) {
989 statusVector[chanId] |= 4;
999 Int_t minBin = proj->GetXaxis()->FindFixBin(pedestalmean[chanId] + 10*pedestalwidth[chanId]);
1000 maxBin = proj->GetXaxis()->GetNbins() - 1;
1001 Int_t hottowerthreshold = minBin;
1004 Float_t nHitsAbovePedestal = proj->Integral(hottowerthreshold,maxBin);
1006 if(nHitsAbovePedestal==0) {
1007 nHitsAbovePedestal=1;
1011 Float_t deadorno = proj->Integral(2,maxBin);
1013 nHitsAbovePedestal=2;
1016 statusVector[chanId] |= mZerobit;
1022 hHotTower->AddAt(nHitsAbovePedestal,chanId);
1041 int numberofnonzerohits = 0;
1043 Short_t bitcompare = (1+2+4+8);
1044 Short_t biton = bitcompare;
1045 Short_t sixteenbiton = 16;
1046 for(Short_t bin=1; bin<maxBin; bin++) {
1047 if(proj->GetBinContent(bin) > 0) {
1050 sixteenbiton &= (bin-1);
1051 numberofnonzerohits++;
1054 Bool_t typea=kFALSE,typeb=kFALSE,typec=kFALSE;
1055 if((bitoff & 16) != 16 || (sixteenbiton & 16) != 0) {
1056 for(Short_t bin=1; bin<maxBin; bin++) {
1057 if(proj->GetBinContent(bin) > 0) {
1072 if((bitoff & bitcompare) != bitcompare && numberofnonzerohits > 10) {
1073 cout <<
"136: " << chanId <<
" bitoff: " << bitoff << endl;
1074 statusVector[chanId] = statusVector[chanId] | (8+128);
1076 if(biton != 0 && numberofnonzerohits > 10) {
1077 cout <<
"72: " << chanId <<
" biton: " << biton << endl;
1078 statusVector[chanId] = statusVector[chanId] | (8+64);
1081 if((bitoff & 16) != 16 && typec && numberofnonzerohits > 10) {
1082 cout <<
"136: " << chanId <<
" 16" << endl;
1083 statusVector[chanId] = statusVector[chanId] | (8+128);
1085 if((sixteenbiton & 16) != 0 && typec && numberofnonzerohits > 10) {
1086 cout <<
"72: " << chanId <<
" 16" << endl;
1087 statusVector[chanId] = statusVector[chanId] | (8+64);
1090 for(Short_t bin=1; bin<maxBin; bin++) {
1091 if(proj->GetBinContent(bin) > 0) {
1094 numberofnonzerohits++;
1099 Float_t entries = proj->Integral(1,proj->GetXaxis()->GetNbins());
1101 statusVector[chanId] |= mZerobit;
1102 if (chanId==50 || chanId==139) cout <<
"entries=0 " << chanId <<
" Status: " << statusVector[chanId] << endl;
1129 statusVector[chanId] |= mZerobit;
1134 unsigned int date = dateStamp;
1135 unsigned int time = timeStamp;
1137 Int_t towerId,nextTowerId;
1138 Bool_t histogramsAreSame;
1145 if(mDetectorFlavor ==
"bemc") {
1149 for(
int crate=1; crate<31; crate++) {
1150 for(
int channel=0; channel<160-1; channel++) {
1151 histogramsAreSame = kTRUE;
1152 barry.GetTowerIdFromCrate(crate, channel, towerId);
1153 barry.GetTowerIdFromCrate(crate, channel+1, nextTowerId);
1155 TH1D* projnow = hist->ProjectionY(
"projTemp2",towerId+1,towerId+1);
1156 TH1D* projnext = hist->ProjectionY(
"projTemp3",nextTowerId+1,nextTowerId+1);
1158 for (Int_t i=1; i<projnow->GetXaxis()->GetNbins() && histogramsAreSame; i++) {
1159 if( projnow->GetBinContent(i) != projnext->GetBinContent(i))
1160 histogramsAreSame = kFALSE;
1162 if(histogramsAreSame) {
1163 statusVector[towerId] |= 256;
1164 statusVector[nextTowerId] |= 256;
1172 for(
int crate=0; crate<6; crate++) {
1173 for(
int channel=0; channel<120-1; channel++) {
1174 histogramsAreSame = kTRUE;
1175 towerId = eemcCrateMap[crate][channel];
1176 nextTowerId = eemcCrateMap[crate][channel+1];
1178 TH1D* projnow = hist->ProjectionY(
"projTemp2",towerId+1,towerId+1);
1179 TH1D* projnext = hist->ProjectionY(
"projTemp3",nextTowerId+1,nextTowerId+1);
1181 for (Int_t i=1; i<projnow->GetXaxis()->GetNbins() && histogramsAreSame; i++) {
1182 if( projnow->GetBinContent(i) != projnext->GetBinContent(i))
1183 histogramsAreSame = kFALSE;
1185 if(histogramsAreSame) {
1186 statusVector[towerId] |= 256;
1187 statusVector[nextTowerId] |= 256;
1195 Float_t sumofhits=0, nbinhits=0, ncratehottowers=0;
1196 Int_t goodTowers = 0;
1197 for(
int i=1; i<mDetectorSize+1; i++) {
1198 if(hHotTower->GetBinContent(i) > 2) {
1199 sumofhits += hHotTower->GetBinContent(i);
1206 averageNumberOfHitsPerChannel = sumofhits/nbinhits;
1207 for(
int i=1; i<mDetectorSize+1; i++) {
1208 if ( i==509 || i==533 || i==1306 || i==1397 || i==1503 || i==1892 || i==1893 || i==2074 || i==2075 ) cout << i <<
" Avg numberHits/chan= " << averageNumberOfHitsPerChannel <<
" for this tower: " << hHotTower->GetBinContent(i) << endl;
1212 if( (hHotTower->GetBinContent(i) > 8*averageNumberOfHitsPerChannel)
1213 || (i==1503 && (hHotTower->GetBinContent(i) > 5*averageNumberOfHitsPerChannel))
1214 || (i==1612 && (hHotTower->GetBinContent(i) > 5*averageNumberOfHitsPerChannel)) ) {
1215 statusVector[i] |= 2;
1216 cout <<
"ID: " << i <<
" average: " << averageNumberOfHitsPerChannel <<
" this tower: " << hHotTower->GetBinContent(i) << endl;
1218 if(hHotTower->GetBinContent(i) < averageNumberOfHitsPerChannel/40) statusVector[i] |= 2+16;
1235 if(mDetectorFlavor ==
"bemc") {
1236 for(
int crate=1; crate<31; crate++) {
1240 for(
int channel=0; channel<160; channel++) {
1241 barry.GetTowerIdFromCrate(crate, channel, towerId);
1242 if(hHotTower->GetBinContent(towerId) > 10*averageNumberOfHitsPerChannel) {
1244 }
else if(hHotTower->GetBinContent(towerId) > 2) {
1245 sumofhits += hHotTower->GetBinContent(towerId);
1249 if(nbinhits == 0 || (nbinhits != 0 && sumofhits/nbinhits < averageNumberOfHitsPerChannel/5) || ncratehottowers >= 40) {
1250 for(
int channel=0; channel<160; channel++) {
1251 barry.GetTowerIdFromCrate(crate, channel, towerId);
1252 statusVector[towerId] |= 2+16;
1257 for(
int crate=0; crate<6; crate++) {
1261 for(
int channel=0; channel<120; channel++) {
1262 towerId = eemcCrateMap[crate][channel];
1263 if(hHotTower->GetBinContent(towerId) > 10*averageNumberOfHitsPerChannel) {
1265 }
else if(hHotTower->GetBinContent(towerId) > 2) {
1266 sumofhits += hHotTower->GetBinContent(towerId);
1270 if(nbinhits == 0 || (nbinhits != 0 && sumofhits/nbinhits < averageNumberOfHitsPerChannel/5) || ncratehottowers >= 30) {
1271 for(
int channel=0; channel<120; channel++) {
1272 towerId = eemcCrateMap[crate][channel];
1273 statusVector[towerId] |= 2+16;
1279 for(
int i=1; i<mDetectorSize+1; i++) {
1280 if(statusVector[i] == 0) {
1282 if (i==50 || i==139) cout <<
"status=1 " << i <<
" Status: " << statusVector[i] << endl;
1284 }
else if(statusVector[i] & mZerobit) {
1286 if (i==50 || i==139) cout <<
"statusVec & mZerobit " << i <<
" Status: " << statusVector[i] << endl;
1290 for(
int i=1; i<mDetectorSize+1; i++) {
1292 if (i==50 || i==139) cout <<
"nbinhits=0 " << i <<
" Status: " << statusVector[i] << endl;
1301 CSMStatusUtils::setDateTimeInfo(
int runnumber,TTree* ttree) {
1303 Int_t thedate, thetime;
1304 TString thedatestring =
"", thetimestring =
"", tmpstr=
"";
1306 ttree->SetBranchAddress(
"thedate",&thedate);
1307 ttree->SetBranchAddress(
"thetime",&thetime);
1309 mRunTimestampMap[runnumber] = thetime;
1310 mRunDatestampMap[runnumber] = thedate;
1317 CSMStatusUtils::getDateTimeString(
int runnumber,TTree* ttree) {
1319 if(ttree) setDateTimeInfo(runnumber,ttree);
1320 Int_t thedate, thetime;
1321 TString thedatestring =
"", thetimestring =
"", tmpstr=
"";
1322 if(mRunTimestampMap.count(runnumber)>0) {
1327 thedate = mRunDatestampMap[runnumber];
1328 thetime = mRunTimestampMap[runnumber];
1333 thedatestring += thedate;
1334 thetimestring += thetime;
1336 for(
int i=0; i<5-TMath::Floor(TMath::Log10(thetime)); i++) tmpstr +=
"0";
1339 TString datetimestring =
"." + thedatestring +
"." + tmpstr + thetimestring +
".";
1340 cout << datetimestring << endl;
1341 return datetimestring;
1347 CSMStatusUtils::saveStatusTablesToASCII(TString directory,
int runnumber) {
1350 if ((dir = gSystem->OpenDirectory(directory)) == NULL)
1351 gSystem->MakeDirectory(directory);
1353 IntToPtrVecShortConstIter first = mRunStatusMapPtr->begin();
1354 IntToPtrVecShortConstIter last = mRunStatusMapPtr->end();
1355 if(runnumber != 0) {
1356 first = mRunStatusMapPtr->find(runnumber);
1360 TString tmpstr, runnumberstring, datetimestring;
1361 for (IntToPtrVecShortConstIter iter = first; iter != last; ++iter) {
1362 int runnumber = iter->first;
1363 runnumberstring =
"";
1364 runnumberstring += runnumber;
1365 datetimestring = getDateTimeString(runnumber);
1366 tmpstr = directory +
"/run" + runnumberstring +
"_" + mDetectorFlavor
1367 + datetimestring +
"badTowers.txt";
1368 ofstream txtout(tmpstr.Data());
1369 for (Int_t i = 1; i <= mDetectorSize; i++) {
1370 txtout << i <<
"\t" << (*(iter->second))[i] << endl;
1381 CSMStatusUtils::getNumberOfChangedTowers(Int_t runnumber) {
1383 IntToPtrVecShortConstIter iter = mRunStatusMapPtr->find(runnumber);
1385 if (iter == mRunStatusMapPtr->begin())
1388 if (iter == mRunStatusMapPtr->end())
1392 IntToPtrVecShortConstIter preIter = iter;
1394 Int_t changedTowers = 0;
1395 vector<Short_t>* statusVector = iter->second;
1396 vector<Short_t>* oldStatusVector = preIter->second;
1397 for (UInt_t i = 1; i < statusVector->size(); i++)
1398 if ((((*statusVector)[i] != 1) && ((*oldStatusVector)[i] == 1)) ||
1399 (((*statusVector)[i] == 1) && ((*oldStatusVector)[i] != 1)))
1402 return changedTowers;
1408 CSMStatusUtils::writePedestals(Int_t runNumber, TString directory,
1409 std::vector<Short_t>& statusVector,
1410 std::vector<Float_t>& pedestalmean,
1411 std::vector<Float_t>& pedestalwidth,
1412 std::vector<Float_t>& pedestalchi) {
1415 TString pedtxtfilename = directory +
"/pedestals/";
1419 if ((dir = gSystem->OpenDirectory(pedtxtfilename.Data())) == NULL)
1420 gSystem->MakeDirectory(pedtxtfilename.Data());
1422 TString runnumber =
"";
1423 runnumber += runNumber;
1424 pedtxtfilename = directory +
"/pedestals/" + mDetectorFlavor
1425 +
"pedestals_for_run_" + runnumber +
".ped";
1426 ofstream pedestalfile(pedtxtfilename.Data());
1427 pedestalfile.setf(ios::left);
1428 pedestalfile << setw(8) <<
"ID" <<
1431 setw(8) <<
"STATUS" << endl;
1433 St_emcPed *bemc_ped=
new St_emcPed(
"bemcPed",1);
1435 cout << t_ped.Status[367] << endl;
1436 TString datetimestring = getDateTimeString(runNumber);
1437 TString pedrootfilename = directory +
"/pedestals/" + mDetectorFlavor
1438 +
"Ped" + datetimestring +
"root";
1439 TFile* fout_status =
new TFile(pedrootfilename.Data(),
"RECREATE");
1441 Short_t shortpedmean,shortpedwidth;
1442 for (UInt_t i = 1; i < statusVector.size(); i++) {
1443 shortpedmean = TMath::Nint(100*pedestalmean[i]);
1444 shortpedwidth = TMath::Nint(100*pedestalwidth[i]);
1445 t_ped.Status[i-1] = statusVector[i];
1446 t_ped.AdcPedestal[i-1] = shortpedmean;
1447 t_ped.AdcPedestalRMS[i-1] = shortpedwidth;
1448 t_ped.ChiSquare[i-1]=pedestalchi[i];
1449 pedestalfile << setw(8) << i <<
1450 setw(8) << setprecision(4) << shortpedmean <<
1451 setw(8) << setprecision(3) << shortpedwidth <<
1452 setw(8) << setprecision(3) << statusVector[i] << endl;
1454 pedestalfile.close();
1456 TString tmpstr =
"rm -f " + pedtxtfilename +
".gz";
1457 gSystem->Exec(tmpstr.Data());
1458 tmpstr =
"gzip " + pedtxtfilename;
1459 gSystem->Exec(tmpstr.Data());
1462 bemc_ped->AddAt(&t_ped,0);
1464 fout_status->Close();
1473 CSMStatusUtils::findFillEnds() {
1475 Float_t runFillNumber, priorRunFillNumber=-1;
1476 int runnumber, priorRunNumber=0;
1477 for (map<Int_t,string>::const_iterator iter = mHistFileMap.begin();
1478 iter != mHistFileMap.end(); ++iter) {
1479 TFile* file =
new TFile(iter->second.c_str(),
"READ");
1480 if (file && file->IsOpen()) {
1481 runnumber = iter->first;
1483 TTree* runTree =
dynamic_cast<TTree*
>(file->Get(
"calinfo"));
1485 runTree->SetBranchAddress(
"fillnum",&runFillNumber);
1486 runTree->GetEvent(0);
1492 if(priorRunNumber != 0) {
1493 if(runFillNumber != priorRunFillNumber)
1494 mFillEndMap[priorRunNumber] = kTRUE;
1496 mFillEndMap[priorRunNumber] = kFALSE;
1499 if(iter == mHistFileMap.end())
1500 mFillEndMap[runnumber] = kTRUE;
1503 priorRunNumber = runnumber;
1504 priorRunFillNumber = runFillNumber;
1517 CSMStatusUtils::makeStatusVersusTimePlot() {
1518 gStyle->SetPalette(1,0);
1519 Int_t runs = mRunStatusMapPtr->size();
1521 if(mDetectorFlavor==
"bemc")
1522 hist =
new TH2F(
"bemcStatus_run",
"bemcStatus vs run",
1523 4801,-0.5,4800.5,runs+1,-0.5,runs+0.5);
1525 hist =
new TH2F(
"eemcStatus_run",
"eemcStatus vs run",
1526 721,-0.5,720.5,runs+1,-0.5,runs+0.5);
1528 hist->GetXaxis()->SetTitle(
"tower id");
1529 hist->GetYaxis()->SetTitle(
"relative run number");
1530 Int_t runNumber = 0;
1531 for (IntToPtrVecShortConstIter iter = mRunStatusMapPtr->begin();
1532 iter != mRunStatusMapPtr->end(); ++iter) {
1533 for (Int_t i=1; i<=mDetectorSize; i++) {
1534 if ((*(iter->second))[i] != 0) {
1535 hist->Fill(i,runNumber,(*(iter->second))[i]);
1543 void CSMStatusUtils::writeHtmlHeaderBadTowerList(ofstream& out,Int_t runnumber) {
1544 out <<
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
1545 out <<
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 STRICT//EN\"" << endl;
1546 out <<
" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" << endl;
1547 out <<
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\" >" << endl;
1548 out <<
"<head>" << endl;
1549 out <<
"<meta content=\"text/html; charset=UTF-8\" />" << endl;
1550 out <<
"<title> Bad BEMC Tower List Run " << runnumber <<
" </title>" << endl;
1551 out <<
"<link rel=\"StyleSheet\" href=\"../../myStyle.css\" type=\"text/css\" />" << endl;
1552 out <<
"</head>" << endl;
1553 out <<
"<body xml:lang=\"en\" lang=\"en\" >" << endl;
1554 out <<
"<h1> Bad BEMC Tower List Run " << runnumber <<
" </h1>" << endl;
1555 out <<
"<div class=\"header\">Status Codes</div>" << endl;
1556 out <<
"(codes are backward compatible with prior status tables)" << endl;
1557 out <<
"<ul>" << endl;
1558 out <<
"<li> 0 == channel does not exist </li>" << endl;
1559 out <<
"<li> 1 == channel is good </li>" << endl;
1560 out <<
"<li> 2 == channel is either hot or cold (see bit 16) </li>" << endl;
1561 out <<
"<li> 4 == channel has a weird pedestal (see bit 32)</li>" << endl;
1562 out <<
"<li> 8 == channel has a stuck bit (see bits 64 and 128) </li>" << endl;
1563 out <<
"<li> 16 == if off, hot tower (10x as many hits as others); if on, " <<
1564 "cold tower (40x fewer hits than others) </li>" << endl;
1565 out <<
"<li> 32 == if off, pedestal mean is out of bounds; if on, " <<
1566 "pedestal width is too large/small</li>" << endl;
1567 out <<
"<li> 64 == bit stuck on</li>" << endl;
1568 out <<
"<li> 128 == bit stuck off</li>" << endl;
1569 out <<
"</ul>" << endl;
1570 out <<
"<div class=\"header\">Bad Tower List</div>" << endl;
1571 out <<
"<p> Tower ADC plots are only available if the tower status has changed"
1572 <<
" compared to the previous run</p>" << endl;
1573 out <<
"<table border=\"1\">" << endl;
1574 out <<
"<tbody>" << endl;
1575 out <<
"<tr> <th width=\"50\"> Tower ID </th> <th width=\"50\"> Status Code </th> <th width=\"100\"> ADC plot </th> </tr>" << endl;
1578 void CSMStatusUtils::writeHtmlFooterBadTowerList(ofstream& out) {
1579 out <<
"</tbody>" << endl;
1580 out <<
"</table>" << endl;
1581 out <<
"<address> Thorsten Kollegger - last updated";
1582 out <<
" 7/30/2004";
1583 out <<
"</address>" << endl;
1584 out <<
"</body>" << endl;
1585 out <<
"</html>" << endl;
1588 void CSMStatusUtils::writeHtmlHeaderSummary(ofstream& out) {
1589 out <<
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
1590 out <<
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 STRICT//EN\"" << endl;
1591 out <<
" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" << endl;
1592 out <<
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\" >" << endl;
1593 out <<
"<head>" << endl;
1594 out <<
"<meta content=\"text/html; charset=UTF-8\" />" << endl;
1595 out <<
"<title> BEMC Tower Status Analysis </title>" << endl;
1596 out <<
"<link rel=\"StyleSheet\" href=\"../../myStyle.css\" type=\"text/css\" />" << endl;
1597 out <<
"</head>" << endl;
1598 out <<
"<body xml:lang=\"en\" lang=\"en\" >" << endl;
1599 ifstream in(
"StRoot/StElectronInvMassAna/CSMStatusUtilsSummary.html");
1600 Char_t buffer[2048];
1601 while (in.is_open()) {
1602 in.getline(buffer,2048);
1606 out << buffer << endl;
1610 void CSMStatusUtils::writeHtmlFooterSummary(ofstream& out) {
1611 out <<
"</tbody>" << endl;
1612 out <<
"</table>" << endl;
1613 out <<
"<address> David Staszak (taken from David Relyea, Thorsten Kollegger) - last updated";
1614 out <<
" 8/20/2006";
1615 out <<
"</address>" << endl;
1616 out <<
"</body>" << endl;
1617 out <<
"</html>" << endl;
Int_t makeStatusPlots(TString plotDir)