Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

TridControl.cxx

Go to the documentation of this file.
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 // SigC:
00009 #include <sigc++/sigc++.h>
00010 #include <sigc++/class_slot.h>
00011 
00012 // Root stuff:
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 // Mode names.
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 // Static members.
00083 map<PageDisplay*,TridControl*> TridControl::sControls;
00084 
00086 // Constructor, destructor
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), // White
00101   fBackgroundColor(0,0,0), // Black
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   // Look for the TriD menu, common to all Pages in the PD.
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   // Setup the trid menu(s).
00127   fMenu = mb.MakeAddMenu("TriD");
00128   
00129   mit = fMenu->Add("Animation...");
00130   (*mit)->Connect(slot_class(fAnimator,&TridAnimator::OpenWindow));
00131 
00132   // Histograms.
00133   fHistoMenu = manage(new GuiMenu);
00134   fMenu->Add("Histograms",*fHistoMenu);
00135 
00137   // Switches.
00138    
00139   // Over and underscale options.
00140   fColorShowUnderScale.AddToMenu(fMenu,"Show Underscale (color)");
00141   fColorShowOverScale. AddToMenu(fMenu,"Show Overscale (color)");
00142   // When hit, change the color.
00143   fColorShowUnderScale.Connect(fSignal_ChangeColor.slot());
00144   fColorShowOverScale.Connect(fSignal_ChangeColor.slot()); 
00145 
00146   // Window menu.
00147   //fWindowMenu = manage(new GuiMenu);
00148   //fMenu->Add("Windows",*fWindowMenu);
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   // Set up the default ranges.
00156 
00157   // Put in some values for all of them, just to cover my ass.
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   // Object is destroyed by the usual SigC mechanism:
00180   // When all pages which track instance drop it,
00181   // it destroys itself.
00182   MSG("TriD",Msg::kDebug) << "~TridControl()" << endl;
00183 
00184   sControls[fPageDisplay] = 0;
00185 }
00186  
00188 // Access
00189    
00190 TridControl* 
00191 TridControl::Instance(PageDisplay* pd) 
00192 {
00193   // Get a trid control pointer.
00194   if(sControls[pd]!=0) return sControls[pd];
00195   TridControl* control = manage(new TridControl(pd));
00196   return control;
00197 }
00198 
00200 // Page registration.
00201 void TridControl::ConnectTridPage(TridPage* page)
00202 {
00203   // Connects each signal to the corresponding slot on the Page.
00204   // Adds the connection for each signal to a map so that the 
00205   // slot can be deleted when the page is.
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 // Histograms.
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   // Update menu.
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   // Set checkmarks appropriately.
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 // Color
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 // Trans
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 // Options and switches
00345 
00346 void TridControl::SaveWindowGeometries() 
00347 {
00348   
00349   TEnv env(fConfigFileName.Data());
00350   env.SetValue("Trid.DefaultWindows","",kEnvChange); // Set up null string.
00351   fSignal_SaveWindowGeometry.emit(env);
00352 
00353   // This line doesn't work because the ROOT Env system has bugs.
00354   //env.SaveLevel(kEnvUser);
00355 
00356   // So, I'll write my own custom save routine here:
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   //char *s = gSystem->ConcatFileName(gSystem->HomeDirectory(), ".tridrc");
00374   TEnv env(fConfigFileName.Data());  
00375   fSignal_RestoreWindowGeometry.emit(env);
00376 }
00377 
00379 // Picking and Selecting
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 // Color stuff.
00421 // color mapping
00422 TVector3 TridControl::GetColor( Float_t x ) 
00423 {
00424   // Map a fractional number x to a place in the current pallete.
00425   // Underscale:
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   // Underscale and overscale: make whiter.
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 // Color and Trans model mapping.
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   // Transform to current scale and get color.
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 // Animation.
00537 
00538 
00540 // File operations.
00542 /*
00543 const char kDefaultFilename[] = {"~/.tridrc"};
00544 
00545 void TridControl::LoadFromFile( const char* filename )
00546 {
00547   TString file = kDefaultFilename;
00548   if(strlen(filename)>0) file = filename;
00549   gSystem->ExpandPathName(file);
00550   if(gSystem->AccessPathName(file.Data())) {
00551     TFile f(file.Data());
00552     TridControl* obj = (TridControl*) f.Get("TridControl");
00553     Copy(*obj);
00554     delete obj;
00555     f.Close();
00556   }
00557 }
00558 
00559 void TridControl::SaveToFile( const char* filename )
00560 {
00561   TString file = kDefaultFilename;
00562   if(strlen(filename)>0) file = filename;
00563   gSystem->ExpandPathName(file);
00564   TDirectory* cd_save = gDirectory;
00565   TFile f(file.Data(),"RECREATE");
00566   f.cd();
00567   Write("TridControl");
00568   f.Write();
00569   f.Close();
00570   cd_save->cd();
00571 }
00572 */

Generated on Sat Nov 21 22:47:56 2009 for loon by  doxygen 1.3.9.1