00001 #include "GfxDigit.h"
00002 #include "GfxDigitList.h"
00003 #include "GfxDigitListCfg.h"
00004 #include "ViewState.h"
00005 #include <Midad/Base/Mint.h>
00006 #include <Midad/Util/Util.h>
00007
00008 #include <UgliGeometry/UgliGeomHandle.h>
00009 #include <UgliGeometry/UgliStripHandle.h>
00010
00011
00012 #include <CandDigit/CandDigitHandle.h>
00013 #include <RecoBase/CandStripHandle.h>
00014 #include <RecoBase/CandSliceHandle.h>
00015
00016 #include <Plex/PlexSEIdAltL.h>
00017 #include <Plex/PlexVetoShieldHack.h>
00018 #include <Midad/Base/ZoomPad.h>
00019 #include <Midad/Util/Range.h>
00020
00021 #include <MessageService/MsgService.h>
00022 CVSID("$Id: GfxDigit.cxx,v 1.14 2005/11/10 17:01:05 musser Exp $");
00023
00024 #include <TEllipse.h>
00025 #include <TBox.h>
00026 #include <TPolyLine.h>
00027 #include <TPad.h>
00028
00029 #include <iostream>
00030 using namespace std;
00031
00032 ClassImp(GfxDigit)
00033
00034 #if 0
00035 GfxDigit::GfxDigit()
00036 : fDigit(0)
00037 ,fParent(0)
00038 ,fImp(0)
00039 {
00040 }
00041 #endif
00042 GfxDigit::GfxDigit(const CandDigitHandle& csh, GfxDigitList& parent)
00043 : fDigit(&csh)
00044 ,fItem(0)
00045 ,fParent(&parent)
00046 ,fImp(0)
00047 {
00048 }
00049 GfxDigit::GfxDigit(const CandDigitHandle& csh,
00050 const PlexSEIdAltLItem& itm, GfxDigitList& parent)
00051 : fDigit(&csh)
00052 ,fItem(&itm)
00053 ,fParent(&parent)
00054 ,fImp(0)
00055 {
00056
00057
00058
00059
00060 }
00061 GfxDigit::GfxDigit(const GfxDigit& rhs)
00062 : TObject()
00063 ,fDigit(rhs.fDigit), fItem(rhs.fItem), fParent(rhs.fParent), fImp(0)
00064 {
00065 }
00066 GfxDigit& GfxDigit::operator=(const GfxDigit& rhs)
00067 {
00068 if (this == &rhs) return *this;
00069 fDigit = rhs.fDigit;
00070 fItem = rhs.fItem;
00071 fParent = rhs.fParent;
00072 fImp = 0;
00073 return *this;
00074 }
00075
00076 GfxDigit::~GfxDigit()
00077 {
00078 this->Clear();
00079 }
00080
00081 void GfxDigit::Clear(const Option_t*)
00082 {
00083 if (fImp) delete fImp; fImp=0;
00084 }
00085
00086 bool GfxDigit::GetRealCoords(double& cx, double& cy, double& dx, double& dy)
00087 {
00088 UgliGeomHandle ugh(*fDigit->GetVldContext());
00089 UgliStripHandle ush;
00090 if (!fItem) {
00091 ush = ugh.GetStripHandle(fDigit->GetPlexSEIdAltL().GetBestItem().GetSEId());
00092 }
00093 else {
00094 ush = ugh.GetStripHandle(fItem->GetSEId());
00095 }
00096
00097 if(!fDigit->GetPlexSEIdAltL().IsVetoShield()){
00098
00099 if (!ush.IsValid()) return false;
00100 cx = ush.GlobalPos(0).Z();
00101 cy = ush.GetTPos();
00102 dx = 1.5*ush.GetHalfThickness();
00103 dy = 1.5*ush.GetHalfWidth();
00104 return true;
00105 }
00106 else{
00107 if (!ush.IsValid())return false;
00108 TVector3 stripxyz0(ush.GlobalPos(-ush.GetHalfLength()));
00109 TVector3 stripxyz1(ush.GlobalPos(ush.GetHalfLength()));
00110
00111 cx = 0.5*(stripxyz0[0]+stripxyz1[0]);
00112 cy = 0.5*(stripxyz0[1]+stripxyz1[1]);
00113 dy = 1.5*ush.GetHalfThickness();
00114 dx = 1.5*ush.GetHalfWidth();
00115 return true;
00116 }
00117 }
00118
00119
00120 bool GfxDigit::GetDiscreteCoords(double& cx, double& cy, double& dx, double& dy)
00121 {
00122 PlexStripEndId seid;
00123
00124 if (!fItem) {
00125 seid = fDigit->GetPlexSEIdAltL().GetBestItem().GetSEId();
00126 }
00127 else {
00128 seid = fItem->GetSEId();
00129 }
00130 cx = seid.GetPlane();
00131 cy = seid.GetStrip();
00132 dx = 0.15;
00133 dy = 0.75;
00134 if (fItem)
00135 MSG("Midad",Msg::kVerbose) << seid.AsString()
00136 << " cx = " << cx
00137 << " cy = " << cy << endl;
00138 return true;
00139 }
00140
00141 float GfxDigit::GetRelativeValue(GfxDigitListCfg::MeasureScale_t ms)
00142 {
00143
00144 const PlexSEIdAltL& altl = fDigit->GetPlexSEIdAltL();
00145 if (ms == GfxDigitListCfg::kCharge) {
00146 RangeDouble& qrange = fParent->GetMint().GetChargeRange();
00147 double den = qrange.Min() - qrange.Max();
00148 if (den > 0)
00149 return (altl.GetBestItem().GetPE() - qrange.Min()) / den;
00150 }
00151 else {
00152 RangeDouble& trange = fParent->GetMint().GetTimeRange();
00153 double den = trange.Max() - trange.Min();
00154 if (den > 0)
00155
00156 return (altl.GetBestItem().GetTime() - trange.Min()) / den;
00157 }
00158 return 1.0;
00159 }
00160
00161 void GfxDigit::ModifyCoords(double& cx, double& cy, double& dx, double& dy)
00162 {
00163 int strip_sign = 0;
00164 if( fDigit->GetPlexSEIdAltL().IsVetoShield()) return;
00165 StripEnd::StripEnd_t end;
00166 if (!fItem) {
00167 end = fDigit->GetPlexSEIdAltL().GetBestItem().GetSEId().GetEnd();
00168 }
00169 else {
00170 end = fItem->GetSEId().GetEnd();
00171 }
00172 if (end == StripEnd::kNegative) strip_sign = -1;
00173 if (end == StripEnd::kPositive) strip_sign = +1;
00174
00175 GfxDigitListCfg& cfg = fParent->GetCfg();
00176
00177
00178 GfxDigitListCfg::SizeBy_t sb = cfg.GetSizeBy();
00179 double size_scale = this->GetRelativeValue(cfg.GetSizeIs());
00180
00181 size_scale *= cfg.GetSizeFactor();
00182
00183 switch (sb) {
00184 case GfxDigitListCfg::kFixed:
00185
00186 break;
00187 case GfxDigitListCfg::kLinear:
00188 dx *= size_scale;
00189 dy *= size_scale;
00190 break;
00191 case GfxDigitListCfg::kLogLinear:
00192 dx *= logify_relative(size_scale);
00193 dy *= logify_relative(size_scale);
00194 break;
00195 case GfxDigitListCfg::kLogArea:
00196 dx *= logify_relative(sqrt(size_scale));
00197 dy *= logify_relative(sqrt(size_scale));
00198 break;
00199 case GfxDigitListCfg::kArea: default:
00200 dx *= sqrt(size_scale);
00201 dy *= sqrt(size_scale);
00202 break;
00203 }
00204
00205
00206 GfxDigitListCfg::DigitEnd_t si = cfg.GetStripEnd();
00207 switch (si) {
00208 case GfxDigitListCfg::kHalf:
00209 dy *= strip_sign * 0.5;
00210 cy += dy;
00211 break;
00212 case GfxDigitListCfg::kBowTie:
00213 dx *= strip_sign * 0.5;
00214 dy *= strip_sign * 0.5;
00215 cx += dx;
00216 cy += dy;
00217 break;
00218 case GfxDigitListCfg::kFull:
00219
00220 case GfxDigitListCfg::kBit:
00221
00222 default:
00223
00224 break;
00225 }
00226 }
00227
00228 bool GfxDigit::SetColor(){
00229
00230 fColor = fParent->GetDigitColor(*fDigit);
00231 if(fItem) {fColor = fParent->GetDigitColor(*fDigit, *fItem);}
00232 Bool_t found=true;
00233 CandSliceHandle * slice = fParent->GetEVD()->GetCandSlice();
00234 if(slice){
00235 found=false;
00236 TIter stripItr(slice->GetDaughterIterator());
00237 while (CandStripHandle *strip = dynamic_cast<CandStripHandle*>
00238 (stripItr())){
00239 TIter digitItr(strip->GetDaughterIterator());
00240 while (CandDigitHandle *dig=dynamic_cast<CandDigitHandle*>(digitItr())) {
00241 if(dig->GetChannelId()==fDigit->GetChannelId() && dig->GetRawDigitIndex()==fDigit->GetRawDigitIndex()){
00242 found=true;
00243 break;
00244 }
00245 }
00246 }
00247 }
00248 CandEventHandle * ev = fParent->GetEVD()->GetCandEvent();
00249 if(ev){
00250 found=false;
00251 TIter stripItr(ev->GetDaughterIterator());
00252 while (CandStripHandle *strip = dynamic_cast<CandStripHandle*>
00253 (stripItr())){
00254 TIter digitItr(strip->GetDaughterIterator());
00255 while (CandDigitHandle *dig=dynamic_cast<CandDigitHandle*>(digitItr())) {
00256 if(dig->GetChannelId()==fDigit->GetChannelId() && dig->GetRawDigitIndex()==fDigit->GetRawDigitIndex()){
00257 found=true;
00258 break;
00259 }
00260 }
00261 }
00262 }
00263 if(fDigit->GetCharge(CalDigitType::kPE)<5)fColor=10;
00264 if(fDigit->GetCharge(CalDigitType::kPE)<2)fColor=20;
00265 if(!found && !fDigit->GetPlexSEIdAltL().IsVetoShield() )fColor=fParent->GetEVD()->GetGhostColor();
00266 if (!fColor){
00267 return false;
00268 }
00269
00270 TAttFill* att_fill = dynamic_cast<TAttFill*>(fImp);
00271 if (!att_fill) return false;
00272 att_fill->SetFillColor(fColor);
00273 if (!fItem) {
00274 att_fill->SetFillStyle(1001);
00275 }
00276 else {
00277 att_fill->SetFillStyle(0);
00278 const PlexSEIdAltLItem& best = fDigit->GetPlexSEIdAltL().GetBestItem();
00279 if ( fItem == &best ) att_fill->SetFillStyle(1001);
00280 }
00281 if(fDigit->GetPlexSEIdAltL().IsVetoShield()) att_fill->SetFillStyle(1001);
00282 TAttLine* att_line = dynamic_cast<TAttLine*>(fImp);
00283 if (!att_line) return false;
00284 att_line->SetLineColor(fColor);
00285 att_line->SetLineWidth(1);
00286
00287 return true;
00288 }
00289
00290 void GfxDigit::Configure()
00291 {
00292
00293 if (fImp) { delete fImp; fImp = 0; }
00294
00295 GfxDigitListCfg& cfg = fParent->GetCfg();
00296
00297 fCx = fCy = fDx = fDy = 0.0;
00298 if((fParent->GetGraphicsView() == GraphicsView::kXY ||
00299 fParent->GetGraphicsView() == GraphicsView::kUV) && (!fDigit->GetPlexSEIdAltL().IsVetoShield()))return;
00300
00301 switch (fParent->GetViewState()->GetSpatialMetric()) {
00302 case ViewState::metric_is_continuous:
00303 this->GetRealCoords(fCx,fCy,fDx,fDy);
00304 break;
00305 case ViewState::metric_is_discreet: default:
00306 this->GetDiscreteCoords(fCx,fCy,fDx,fDy);
00307 break;
00308 }
00309
00310
00311 double dx = fDx, dy = fDy;
00312 if (cfg.GetScaleIs() == GfxDigitListCfg::kAbsolute) {
00313 fDx = 1.0;
00314 fDy = 4.0;
00315 this->ModifyCoords(fCx,fCy,fDx,fDy);
00316 this->RelToAbs(dx,dy);
00317 }
00318 else {
00319 this->ModifyCoords(fCx,fCy,fDx,fDy);
00320 }
00321
00322 switch (cfg.GetShapeIs()) {
00323 case GfxDigitListCfg::kEllipse:
00324 fImp = new TEllipse(fCx,fCy,dx,dy);
00325 break;
00326 default:
00327 if(!fDigit->GetPlexSEIdAltL().IsVetoShield()){
00328 fImp = new TBox(fCx+dx,fCy+dy,fCx-dx,fCy-dy);
00329 }
00330 else {
00331 Double_t dylist[5] = {-dy,-dy,dy,dy,-dy};
00332 Double_t dxlist[5] = {-dx,dx,dx,-dx,-dx};
00333 Double_t rot=0.9;
00334 if(fDigit->GetPlexSEIdAltL().GetPlaneView()==PlaneView::kVSWallOnEdge){
00335 for (int id=0;id<6;id++){
00336 double tmp=dylist[id];
00337 dylist[id]=dxlist[id];
00338 dxlist[id]=tmp;
00339 }
00340 }
00341 if(fDigit->GetPlexSEIdAltL().GetPlaneView()==PlaneView::kVSTopEastSlant){
00342 double newdx;
00343 double newdy;
00344 for (int id=0;id<6;id++){
00345 newdx=dxlist[id]*cos(-rot)+dylist[id]*sin(-rot);
00346 newdy=-dxlist[id]*sin(-rot)+dylist[id]*cos(-rot);
00347 dxlist[id]=newdx;
00348 dylist[id]=newdy;
00349 }
00350 }
00351 if(fDigit->GetPlexSEIdAltL().GetPlaneView()==PlaneView::kVSTopWestSlant){
00352 double newdx;
00353 double newdy;
00354 for (int id=0;id<6;id++){
00355 newdx=dxlist[id]*cos(rot)+dylist[id]*sin(rot);
00356 newdy=-dxlist[id]*sin(rot)+dylist[id]*cos(rot);
00357 dxlist[id]=newdx;
00358 dylist[id]=newdy;
00359 }
00360 }
00361 Double_t xbox[5]={fCx+dxlist[0],fCx+dxlist[1],fCx+dxlist[2],fCx+dxlist[3],fCx+dxlist[0]};
00362 Double_t ybox[5]={fCy+dylist[0],fCy+dylist[1],fCy+dylist[2],fCy+dylist[3],fCy+dylist[0]};
00363 fImp = new TPolyLine(5,xbox,ybox);
00364 }
00365 break;
00366 }
00367 }
00368
00369
00370 void GfxDigit::ExecuteEvent(int event, int px, int py)
00371 {
00372 fParent->ExecuteEvent(event,px,py,this);
00373 }
00374 void GfxDigit::Paint(Option_t* option)
00375 {
00376 if (!fImp) return;
00377 if (fParent->DigitsHidden()) return;
00378 if (!this->SetColor()) return;
00379
00380 GfxDigitListCfg& cfg = fParent->GetCfg();
00381 if (cfg.GetScaleIs() == GfxDigitListCfg::kAbsolute) {
00382 double dx, dy;
00383 this->RelToAbs(dx,dy);
00384 switch (cfg.GetShapeIs()) {
00385 case GfxDigitListCfg::kEllipse: {
00386 TEllipse* el= dynamic_cast<TEllipse*>(fImp);
00387 el->SetR1(dx);
00388 el->SetR2(dy);
00389 el->Paint(option);
00390 break;
00391 }
00392 default:
00393 TBox* box = dynamic_cast<TBox*>(fImp);
00394 box->SetX1(fCx+dx);
00395 box->SetY1(fCy+dy);
00396 box->SetX2(fCx-dx);
00397 box->SetY2(fCy-dy);
00398 box->Paint();
00399 break;
00400 }
00401 }
00402 else {
00403 fImp->Paint(option);
00404 }
00405 }
00406
00407 int GfxDigit::DistancetoPrimitive(int px, int py)
00408 {
00409 if (fImp) return fImp->DistancetoPrimitive(px,py);
00410 return 0xdead;
00411 }
00412
00413 void GfxDigit::RelToAbs(double& dx, double& dy)
00414 {
00415 dx = gPad->AbsPixeltoX((int)fDx) - gPad->AbsPixeltoX(0);
00416 dy = gPad->AbsPixeltoY((int)fDy) - gPad->AbsPixeltoY(0);
00417
00418 }
00419
00420 void GfxDigit::ConfigGui(void)
00421 {
00422 if (!fParent) return;
00423 GfxDigitListCfg& cfg = fParent->GetCfg();
00424 cfg.GuiConfig();
00425 }