00001 #include "TridControl.h"
00002 #include "TridModel.h"
00003 #include "TridPage.h"
00004
00005 #include "MessageService/MsgService.h"
00006 #include "Midad/Base/PageDisplay.h"
00007 #include "Conventions/Munits.h"
00008
00009 #include <sigc++/sigc++.h>
00010 #include <sigc++/class_slot.h>
00011
00012
00013 #include <TStyle.h>
00014 #include <TColor.h>
00015 #include <TROOT.h>
00016 #include <TSystem.h>
00017 #include <TFile.h>
00018 #include <TTimer.h>
00019 #include <TEnv.h>
00020 #include <TOrdCollection.h>
00021 #include <THashList.h>
00022
00023 #include <math.h>
00024 #include <algorithm>
00025
00026 class SelectionInfoPage;
00027
00028 using namespace std;
00029
00030 CVSID("$Id: TridControl.cxx,v 1.26 2007/02/01 22:24:00 rhatcher Exp $");
00031 using namespace SigC;
00032
00033
00034
00035 const char* kColorModeNames[TridControl::kNumColorModes] =
00036 {
00037 "Charge (MIPs)",
00038 "Charge (ADC Counts)",
00039 "Charge (PEs)",
00040 "Mean Time (raw) (ns)",
00041 "Mean Time (-t0) (ns)",
00042 "Earliest Time (raw) (ns)",
00043 "Earliest Time (-t0) (ns)",
00044 "Occupancy"
00045 };
00046
00047 const char* kTransModeNames[TridControl::kNumTransModes] =
00048 {
00049 "None",
00050 "Constant",
00051 "Charge (MIPs)",
00052 "Charge (ADC Counts)",
00053 "Charge (PEs)",
00054 "Mean Time (raw) (ns)",
00055 "Mean Time (-t0) (ns)",
00056 };
00057
00058
00059 const double kColorModeStartRanges[TridControl::kNumColorModes][2] =
00060 {{ 0, 20 },
00061 { 0, 2000 },
00062 { 0, 20 },
00063 { 0, 200 },
00064 { 0, 200 },
00065 { 0, 200 },
00066 { 0, 200 },
00067 { 0, 4 }
00068 };
00069
00070 const double kTransModeStartRanges[TridControl::kNumTransModes][2] =
00071 { { 0, 1.2 },
00072 { 0, 1.2, },
00073 { 0, 20 },
00074 { 0, 2000 },
00075 { 0, 20 },
00076 { 0, 200 },
00077 { 0, 200 },
00078 };
00079
00080 ClassImp(TridControl)
00081
00082
00083 map<PageDisplay*,TridControl*> TridControl::sControls;
00084
00086
00087
00088 TridControl::TridControl(PageDisplay* pd):
00089 fPageDisplay(pd),
00090 fMenu(0),
00091 fHistoMenu(0),
00092 fCurrentHistoName(""),
00093 fPick(0),
00094 fSelection(),
00095 fColorMode(kColorAsChargeADC),
00096 fTransMode(kTransConstant),
00097 fColorShowUnderScale(true),
00098 fColorShowOverScale(true),
00099 fInterpolateColor(true),
00100 fForegroundColor(1,1,1),
00101 fBackgroundColor(0,0,0),
00102 fSelectionInfoPage(0),
00103 fAnimator(*this)
00104 {
00105 const char* confFile = gSystem->Getenv("TRID_CONFIG_FILE");
00106 if(confFile) {
00107 MSG("TriD",Msg::kInfo) << "Loading config data from " << confFile << endl;
00108 fConfigFileName = confFile;
00109 }
00110 else
00111 fConfigFileName = ".tridrc";
00112
00113 sControls[fPageDisplay] = this;
00114 MSG("TriD",Msg::kDebug) << "TridControl Constructor!" << endl;
00115
00116
00117 GuiMenuBar& mb = fPageDisplay->GetMenuBar();
00118 GuiMenu* fMenu = mb.GetMenu("TriD");
00119 GuiMenu::GuiMenuList::iterator mit;
00120
00121 if(fMenu) {
00122 MSG("TriD",Msg::kError) << "TridControl Constructor: Menu already exists in PageDisplay!" << endl;
00123 return;
00124 }
00125
00126
00127 fMenu = mb.MakeAddMenu("TriD");
00128
00129 mit = fMenu->Add("Animation...");
00130 (*mit)->Connect(slot_class(fAnimator,&TridAnimator::OpenWindow));
00131
00132
00133 fHistoMenu = manage(new GuiMenu);
00134 fMenu->Add("Histograms",*fHistoMenu);
00135
00137
00138
00139
00140 fColorShowUnderScale.AddToMenu(fMenu,"Show Underscale (color)");
00141 fColorShowOverScale. AddToMenu(fMenu,"Show Overscale (color)");
00142
00143 fColorShowUnderScale.Connect(fSignal_ChangeColor.slot());
00144 fColorShowOverScale.Connect(fSignal_ChangeColor.slot());
00145
00146
00147
00148
00149 mit = fMenu->Add("Save Configuration");
00150 (*mit)->Connect(slot_class(*this,&TridControl::SaveWindowGeometries));
00151 mit = fMenu->Add("Restore Configuration");
00152 (*mit)->Connect(slot_class(*this,&TridControl::RestoreWindowGeometries));
00153
00154
00155
00156
00157
00158 for(int i=0;i<kNumColorModes;i++) {
00159 fColorRanges[i].SetName(kColorModeNames[i]);
00160 fColorRanges[i].Set(
00161 kColorModeStartRanges[i][0],
00162 kColorModeStartRanges[i][1]
00163 );
00164 }
00165
00166 for(int i=0;i<kNumTransModes;i++) {
00167 fColorRanges[i].SetName(kColorModeNames[i]);
00168 fTransRanges[i].Set(
00169 kTransModeStartRanges[i][0],
00170 kTransModeStartRanges[i][1]
00171 );
00172 }
00173
00174 }
00175
00176
00177 TridControl::~TridControl()
00178 {
00179
00180
00181
00182 MSG("TriD",Msg::kDebug) << "~TridControl()" << endl;
00183
00184 sControls[fPageDisplay] = 0;
00185 }
00186
00188
00189
00190 TridControl*
00191 TridControl::Instance(PageDisplay* pd)
00192 {
00193
00194 if(sControls[pd]!=0) return sControls[pd];
00195 TridControl* control = manage(new TridControl(pd));
00196 return control;
00197 }
00198
00200
00201 void TridControl::ConnectTridPage(TridPage* page)
00202 {
00203
00204
00205
00206 std::vector<Connection> list;
00207 list.push_back(fSignal_ChangeColor.connect ((slot_class(*page,&TridPage::ChangeColorHook) )));
00208 list.push_back(fSignal_ChangeTrans.connect ((slot_class(*page,&TridPage::ChangeTransHook) )));
00209 list.push_back(fSignal_ChangePicked.connect ((slot_class(*page,&TridPage::ChangePickedHook) )));
00210 list.push_back(fSignal_ChangeSelected.connect ((slot_class(*page,&TridPage::ChangeSelectedHook) )));
00211 list.push_back(fSignal_ChangeHistograms.connect((slot_class(*page,&TridPage::ChangeHistogramsHook) )));
00212 list.push_back(fSignal_Animation.connect ((slot_class(*page,&TridPage::AnimationHook) )));
00213 list.push_back(fSignal_SaveWindowGeometry.connect ((slot_class(*page,&TridPage::SaveWindowGeometry) )));
00214 list.push_back(fSignal_RestoreWindowGeometry.connect((slot_class(*page,&TridPage::RestoreWindowGeometry) )));
00215 for(UInt_t i = 0; i<list.size(); i++) {
00216 fConnections.insert(pair<TridPage*,Connection>(page,list[i]));
00217 }
00218 }
00219 void TridControl::DisconnectTridPage(TridPage* page)
00220 {
00221 typedef std::multimap<TridPage*,Connection>::iterator my_it;
00222 pair<my_it,my_it> range;
00223 range = fConnections.equal_range(page);
00224 for(my_it it = range.first; it != range.second; it++) {
00225 it->second.disconnect();
00226 }
00227
00228 }
00229
00230
00232
00234
00235 void TridControl::AddHistograms(const char* pageName, TH1* colorhist, TH1* transhist )
00236 {
00237 string s(pageName);
00238 fColorHistograms[s] = colorhist;
00239 fTransHistograms[s] = transhist;
00240
00241
00242 GuiMenu::GuiMenuList::iterator mit;
00243 mit = fHistoMenu->Add(pageName);
00244 (*mit)->Connect(bind(bind(bind(slot_class(*this,&TridControl::HistoMenuHandler),
00245 s), mit), fHistoMenu));
00246 if(fCurrentHistoName=="") {
00247 fHistoMenu->CheckEntry(mit);
00248 fCurrentHistoName=s;
00249 }
00250 }
00251
00252 TH1* TridControl::GetColorHistogram()
00253 {
00254 return fColorHistograms[fCurrentHistoName];
00255 }
00256
00257 TH1* TridControl::GetTransHistogram()
00258 {
00259 return fTransHistograms[fCurrentHistoName];
00260 }
00261
00262 void TridControl::HistoMenuHandler(GuiMenu* menu,
00263 GuiMenu::GuiMenuList::iterator mit,
00264 string item )
00265 {
00266
00267 GuiMenu::GuiMenuList& mlist = menu->GetMenuList();
00268 GuiMenu::GuiMenuList::iterator it, done = mlist.end();
00269 for (it = mlist.begin(); it != done; ++it)
00270 menu->CheckEntry(it,false);
00271 menu->CheckEntry(mit,true);
00272 fCurrentHistoName=item;
00273 fSignal_ChangeHistograms.emit();
00274 }
00275
00276
00277
00278
00280
00282 void TridControl::ChangeColorMode( int mode )
00283 {
00284 MSG("TriD",Msg::kDebug) << "Color mode change requested to " << mode << endl;
00285 if((mode < kNumColorModes) ) {
00286 fColorMode.SetState(mode);
00287 fSignal_ChangeColor.emit();
00288 }
00289 }
00290
00291 void TridControl::ChangeColorRange( double min, double max )
00292 {
00293 fColorRanges[fColorMode()].Set(min,max);
00294 fSignal_ChangeColor.emit();
00295 }
00296
00297 void TridControl::GetColorRange( double &min, double &max )
00298 {
00299 min = fColorRanges[fColorMode()].Min();
00300 max = fColorRanges[fColorMode()].Max();
00301 }
00302
00303 const char* TridControl::GetColorModeName()
00304 {
00305 return kColorModeNames[fColorMode()];
00306 }
00307
00308
00309
00311
00313 void TridControl::ChangeTransMode( int mode )
00314 {
00315 MSG("TriD",Msg::kDebug) << "Trans mode change requested to " << mode << endl;
00316 if((mode < kNumTransModes) ) {
00317 fTransMode.SetState(mode);
00318
00319 fSignal_ChangeTrans.emit();
00320 }
00321 }
00322
00323 void TridControl::ChangeTransRange( double min, double max )
00324 {
00325 fTransRanges[fTransMode()].Set(min,max);
00326 fSignal_ChangeTrans.emit();
00327 }
00328
00329 void TridControl::GetTransRange( double &min, double &max )
00330 {
00331 min = fTransRanges[fTransMode()].Min();
00332 max = fTransRanges[fTransMode()].Max();
00333 }
00334
00335 const char* TridControl::GetTransModeName()
00336 {
00337 return kTransModeNames[fTransMode()];
00338 }
00339
00340
00341
00343
00345
00346 void TridControl::SaveWindowGeometries()
00347 {
00348
00349 TEnv env(fConfigFileName.Data());
00350 env.SetValue("Trid.DefaultWindows","",kEnvChange);
00351 fSignal_SaveWindowGeometry.emit(env);
00352
00353
00354
00355
00356
00357 TIter next(env.GetTable());
00358 TEnvRec* er;
00359 FILE* outfile = fopen(fConfigFileName.Data(),"w+");
00360 if(!outfile) return;
00361 while((er= (TEnvRec*) next())) {
00362 const char* val = env.GetValue(er->GetName(),"");
00363 fprintf(outfile, "%-40s %s\n",
00364 Form("%s:", er->GetName()),
00365 val );
00366 }
00367 fclose(outfile);
00368
00369 }
00370
00371 void TridControl::RestoreWindowGeometries()
00372 {
00373
00374 TEnv env(fConfigFileName.Data());
00375 fSignal_RestoreWindowGeometry.emit(env);
00376 }
00377
00379
00381
00382 bool TridControl::IsPicked(const TridModel* model)
00383 {
00384 if(fPick)
00385 if(fPick->Intersects(model)) return true;
00386 return false;
00387 }
00388
00389 void TridControl::ClearSelected()
00390 {
00391 fSelection.clear();
00392 }
00393
00394 void TridControl::ToggleSelected(const TridModel* model)
00395 {
00396 std::set<const TridModel*>::iterator it;
00397 it = fSelection.find(model);
00398 if(it==fSelection.end()) {
00399 fSelection.insert(model);
00400 } else {
00401 fSelection.erase(it);
00402 }
00403 }
00404
00405 Bool_t TridControl::IsSelected(const TridModel* model)
00406 {
00407 std::set<const TridModel*>::iterator it = fSelection.begin();
00408 std::set<const TridModel*>::iterator end= fSelection.end();
00409 for( ; it!=end; it++ ) {
00410 if( (*it)->Intersects(model) ) return true;
00411 }
00412
00413 return false;
00414 }
00415
00416
00417
00419
00421
00422 TVector3 TridControl::GetColor( Float_t x )
00423 {
00424
00425
00426 int n = gStyle->GetNumberOfColors();
00427 int index = (int)(floor((x*(float)n)));
00428 if(index>=n) index = n-1;
00429 if(index<0) index = 0;
00430 int colNum = gStyle->GetColorPalette(index);
00431 TColor* colref = gROOT->GetColor(colNum);
00432 TVector3 rgb(colref->GetRed(),colref->GetGreen(),colref->GetBlue());
00433
00434
00435 if((x<.00) || (x>1.0)) {
00436 rgb = rgb + TVector3(.4,.4,.4);
00437 if(rgb.x()>1) rgb.SetX(1);
00438 if(rgb.y()>1) rgb.SetY(1);
00439 if(rgb.z()>1) rgb.SetZ(1);
00440 return rgb;
00441 }
00442
00443 if(!fInterpolateColor) {
00444 return rgb;
00445 }
00446 if(index+1>=n) return rgb;
00447 int colNum2 = gStyle->GetColorPalette(index+1);
00448 TColor* colref2 = gROOT->GetColor(colNum2);
00449 TVector3 rgb2(colref2->GetRed(),colref2->GetGreen(),colref2->GetBlue());
00450 double frac = fmod(x*(double)n,1.0);
00451 TVector3 interp = (1.0-frac)*rgb + (frac)*rgb2;
00452 return interp;
00453 }
00454
00455
00457
00459 Double_t TridControl::GetRangedModelColor(TridModel* model)
00460 {
00461 double x = 0;
00462
00463 switch(fColorMode()) {
00464 case kColorAsChargeMIP:
00465 x = model->GetTotalCharge(CalStripType::kSigCorr);
00466 break;
00467
00468 case kColorAsChargeADC:
00469 x = model->GetTotalCharge(CalStripType::kNone);
00470 break;
00471
00472 case kColorAsChargePE:
00473 x = model->GetTotalCharge(CalStripType::kPE);
00474 break;
00475
00476 case kColorAsTimeMean:
00477 x = model->GetMeanTime(CalTimeType::kNone)/Munits::nanosecond;
00478 break;
00479
00480 case kColorAsTimeMeanT0:
00481 x = model->GetMeanTime(CalTimeType::kT0)/Munits::nanosecond;
00482 break;
00483
00484 case kColorAsTimeEarliest:
00485 x = model->GetEarliestTime(CalTimeType::kNone)/Munits::nanosecond;
00486 break;
00487
00488 case kColorAsTimeEarliestT0:
00489 x = model->GetEarliestTime(CalTimeType::kT0)/Munits::nanosecond;
00490 break;
00491
00492 case kColorAsOccupancy:
00493 x = model->GetOccupancy();
00494 break;
00495
00496 default:
00497 MSG("TriD",Msg::kError) << "Color mode not implimented!" << endl;
00498 }
00499
00500
00501 return fColorRanges[fColorMode()].RelativeUnclipped(x);
00502 }
00503
00504 Double_t TridControl::GetRangedModelTrans( TridModel* model )
00505 {
00506 Float_t x = 1.0;
00507 switch(fTransMode()) {
00508 case kTransNone: return 1.0;
00509 case kTransConstant:
00510 x = 1.0;
00511 break;
00512 case kTransAsChargeMIP:
00513 x = model->GetTotalCharge(CalStripType::kSigCorr);
00514 break;
00515 case kTransAsChargeADC:
00516 x = model->GetTotalCharge(CalStripType::kNone);
00517 break;
00518 case kTransAsChargePE:
00519 x = model->GetTotalCharge(CalStripType::kPE);
00520 break;
00521 case kTransAsMeanTime:
00522 x = model->GetMeanTime(CalTimeType::kNone)/Munits::nanosecond;
00523 break;
00524 case kTransAsMeanTimeT0:
00525 x = model->GetMeanTime(CalTimeType::kT0)/Munits::nanosecond;
00526 break;
00527 default:
00528 MSG("TriD",Msg::kError) << "Trans mode not implimented!" << endl;
00529 }
00530
00531 return fTransRanges[fTransMode()].RelativeUnclipped(x);
00532 }
00533
00535
00537
00538
00540
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572