00001 #include <TString.h>
00002 #include <TColor.h>
00003 #include <iostream>
00004 #include "TMath.h"
00005 #include "math.h"
00006
00007 #include "BesVisLib/Emc2DCrystal.h"
00008 #include "BesVisLib/BesView.h"
00009 #include "BesVisLib/BesCursor.h"
00010
00011 using namespace std;
00012
00013 #ifndef __CINT__
00014 ClassImp(Emc2DCrystal)
00015 #endif
00016
00017
00018
00019 Emc2DCrystal::Emc2DCrystal() {
00020
00021 }
00022
00023
00024
00025 Emc2DCrystal::Emc2DCrystal(const char* name, const char* title, Int_t N, Double_t *P, Int_t part, Int_t theta)
00026 {
00027 SetName(name);
00028 SetTitle(title);
00029 fTip = 0;
00030 fHighlighted = false;
00031 fFired = false;
00032 fPart = part;
00033 fTheta = theta;
00034
00035 fTime = 0.0;
00036 fCharge = 0.0;
00037
00038 fZRSectionTolerance[1] = 0.1;
00039 fZRSectionTolerance[2] = fZRSectionTolerance[0] = 1.2;
00040
00041
00042
00043 Double_t Pxy[3*5];
00044 if (N == 8) {
00045 Int_t iXYSeq[4] = {0,2,6,4};
00046 for (Int_t i = 0; i < 4; i++) {
00047 if (part == 1) {
00048 for (Int_t j = 0; j < 3; j++) {
00049 Pxy[3*i+j] = ( P[3*iXYSeq[i]+j] + P[3*(iXYSeq[i]+1)+j] )/2.0;
00050 }
00051 }
00052 else if (part == 0) {
00053 SetXYPoint(&P[3*i], &P[3*(i+4)], &Pxy[3*i], ecXYPointZ);
00054
00055 }
00056 else if (part == 2) {
00057 SetXYPoint(&P[3*i], &P[3*(i+4)], &Pxy[3*i], -ecXYPointZ);
00058
00059 }
00060
00061
00062 }
00063
00064 fCrystalXY = new BesPolygon2D(name, title, 4, &Pxy[0]);
00065 fCrystalXYFired = new BesPolygon2D(name, title, 4, &Pxy[0]);
00066 }
00067 if (N == 16) {
00068 Int_t iXYSeq[5] = {8,9,1,2,3};
00069 for (Int_t i = 0; i < 5; i++) {
00070 if (part == 0) {
00071 SetXYPoint(&P[3*iXYSeq[i]], &P[3*(iXYSeq[i]+4)], &Pxy[3*i], ecXYPointZ);
00072 }
00073 else if (part == 2) {
00074 SetXYPoint(&P[3*iXYSeq[i]], &P[3*(iXYSeq[i]+4)], &Pxy[3*i], -ecXYPointZ);
00075 }
00076
00077 }
00078
00079 fCrystalXY = new BesPolygon2D(name, title, 5, &Pxy[0]);
00080 fCrystalXYFired = new BesPolygon2D(name, title, 5, &Pxy[0]);
00081 }
00082
00083
00084
00085 Double_t Pzr[3*4];
00086 Int_t iSeq[8] = {0,3,1,2,5,6,4,7};
00087 for (Int_t i = 0; i < 4; i++) {
00088 for (Int_t j = 0; j < 3; j++) {
00089 Pzr[3*i+j] = (P[3*iSeq[2*i]+j] + P[3*iSeq[2*i+1]+j])/2.0;
00090 }
00091
00092 }
00093
00094
00095 fCrystalZR = new BesPolygon2D(TString(name)+TString("zr"), title, 4, &Pzr[0]);
00096 fCrystalZRFired = new BesPolygon2D(TString(name)+TString("zr"), title, 4, &Pzr[0]);
00097
00098 if (N == 8) {
00099 if (GetPart() == 1) {
00100 fPhiMin = GetAngle( P[3*0], P[3*0+1] );
00101 fPhiMax = GetAngle( P[3*3], P[3*3+1] );
00102 }
00103 else {
00104 fPhiMin = GetAngle( P[3*3], P[3*3+1] );
00105 fPhiMax = GetAngle( P[3*0], P[3*0+1] );
00106 }
00107 }
00108 else if (N == 16) {
00109 fPhiMin = GetAngle( P[3*3], P[3*3+1] );
00110 fPhiMax = GetAngle( P[3*8], P[3*8+1] );
00111 }
00112
00113 if (fPhiMin > fPhiMax && fabs(fPhiMax-fPhiMin) < 180.0) {
00114 Double_t phiTemp = fPhiMin;
00115 fPhiMin = fPhiMax;
00116 fPhiMax = phiTemp;
00117 }
00118
00119
00120
00121
00122 Double_t Pside[3*5];
00123 if (N == 8) {
00124
00125 for (Int_t i = 0; i < 4; i++) {
00126 if (part == 1) {
00127 SetZRPoint(&P[3*i], &P[3*(i+4)], &Pside[3*i], brZRPointR);
00128 }
00129 else {
00130 ProjectECToSide(&Pxy[3*i], &Pside[3*i]);
00131 }
00132 }
00133
00134 fCrystalSide = new BesPolygon2D(name, title, 4, &Pside[0]);
00135 fCrystalSideFired = new BesPolygon2D(name, title, 4, &Pside[0]);
00136 }
00137 if (N == 16) {
00138 for (Int_t i = 0; i < 5; i++) {
00139 ProjectECToSide(&Pxy[3*i], &Pside[3*i]);
00140 }
00141
00142 fCrystalSide = new BesPolygon2D(name, title, 5, &Pside[0]);
00143 fCrystalSideFired = new BesPolygon2D(name, title, 5, &Pside[0]);
00144 }
00145
00146
00147
00148 SetStyle();
00149
00150 fTip = new BesPaveText(0, 0, 0.45, 0.08);
00151 CloseInfo();
00152 }
00153
00154
00155
00156 Emc2DCrystal::~Emc2DCrystal() {
00157
00158 if (fCrystalXY) delete fCrystalXY;
00159 if (fCrystalZR) delete fCrystalZR;
00160 if (fCrystalXYFired) delete fCrystalXYFired;
00161 if (fCrystalZRFired) delete fCrystalZRFired;
00162 }
00163
00164 void Emc2DCrystal::SetStyle()
00165 {
00166 lcCrystal = 15;
00167 lwCrystal = 1;
00168 fcCrystal = 1005;
00169 fsCrystal = 1001;
00170 fsCrystalTrans = 4000;
00171
00172 lcCrystalFired = kRed;
00173 lwCrystalFired = 1;
00174 fcCrystalFired = kRed;
00175 fsCrystalFired = 1001;
00176
00177 lcCrystalHL = lcCrystal;
00178 lwCrystalHL = 1;
00179 fcCrystalHL = kBlue;
00180 fsCrystalHL = 1001;
00181
00182 lcCrystalFiredHL = kRed;
00183 lwCrystalFiredHL = 2;
00184 fcCrystalFiredHL = kWhite;
00185 fsCrystalFiredHL = 4000;
00186 }
00187
00188 void Emc2DCrystal::ClearInfo()
00189 {
00190 fInfoCon.clear();
00191 fTip->DeleteText();
00192 }
00193
00194 void Emc2DCrystal::CloseInfo()
00195 {
00196 if (fTip) {
00197 fTip->Clear();
00198
00199 if (fInfoCon.size() == 0) fInfoCon.push_back(GetTitle());
00200 fTip->SetText(fInfoCon);
00201 }
00202 else
00203 cout << "Emc2DCrystal::CloseInfo, not initialized" << endl;
00204 }
00205
00206
00207
00208 Int_t Emc2DCrystal::DistancetoPrimitive(Int_t px, Int_t py) {
00209
00210 BesView *view = (BesView*)gPad->GetView();
00211 if ( view->GetViewType() & kXYView ) {
00212 if ( fCrystalXY && IsXYVisible() ) {
00213 return fCrystalXY->DistancetoPrimitive(px, py);
00214 }
00215 }
00216 else if ( view->GetViewType() & kZRView && fCrystalZR && fCrystalSide ) {
00217 if (HasZRSection())
00218 return fCrystalZR->DistancetoPrimitive(px, py);
00219 else if ( IsSideVisible() &&
00220 (view->GetVisEmcSide() || (view->GetVisEmcHitsSide() && IsFired())) )
00221 return fCrystalSide->DistancetoPrimitive(px, py);
00222 }
00223
00224 return 9999;
00225 }
00226
00227
00228
00229 void Emc2DCrystal::ExecuteEvent(Int_t event, Int_t px, Int_t py) {
00230
00231
00232
00233
00234
00235 BesView *view = (BesView*)gPad->GetView();
00236
00237 if (gBesCursor->GetType() == kBesHand) {
00238 if (view) view->ExecuteEvent(event, px, py);
00239 }
00240 else if (gBesCursor->GetType() == kBesPick){
00241
00242 if (gPad) gPad->SetCursor(kPointer);
00243
00244 switch (event) {
00245
00246 case kMouseEnter :
00247 this->SetHighlighted(true);
00248
00249
00250 Draw();
00251
00252 fTip->SetPos(px, py);
00253 view->UpdateView(0);
00254
00255 fTip->Draw("BR,SAME");
00256 gPad->Modified();
00257 gPad->Update();
00258 break;
00259
00260 case kMouseLeave:
00261 if (this->IsHighlighted()) {
00262 this->SetHighlighted(false);
00263
00264 Draw();
00265
00266
00267
00268
00269
00270
00271
00272
00273 view->UpdateView(0);
00274 gPad->Modified();
00275 gPad->Update();
00276 break;
00277 }
00278 }
00279 }
00280 }
00281
00282
00283
00284 void Emc2DCrystal::Draw(Option_t *option) {
00285
00286
00287 TString opt = option;
00288 opt.ToUpper();
00289
00290 AppendPad(option);
00291 }
00292
00293
00294
00295 void Emc2DCrystal::Paint(Option_t *option) {
00296
00297 TString opt = option;
00298 opt.ToUpper();
00299
00300 BesView *view = (BesView*)gPad->GetView();
00301 if (view->GetViewType() & kXYView) {
00302
00303 if (fCrystalXY) {
00304 fCrystalXY->SetLineColor(lcCrystal);
00305 fCrystalXY->SetLineWidth(lwCrystal);
00306 fCrystalXY->SetFillColor(fcCrystal);
00307 fCrystalXY->SetFillStyle(fsCrystal);
00308 }
00309
00310 if (this->IsFired()) {
00311 if (fCrystalXY) {
00312 fCrystalXY->SetFillStyle(fsCrystalTrans);
00313 }
00314 if (fCrystalXYFired) {
00315 fCrystalXYFired->SetLineColor(lcCrystalFired);
00316 fCrystalXYFired->SetLineWidth(lwCrystalFired);
00317 fCrystalXYFired->SetFillColor(fcCrystalFired);
00318 fCrystalXYFired->SetFillStyle(fsCrystalFired);
00319 }
00320 }
00321
00322 if (this->IsHighlighted()) {
00323 if (fCrystalXY) {
00324 fCrystalXY->SetLineColor(lcCrystalHL);
00325 fCrystalXY->SetLineWidth(lwCrystalHL);
00326 fCrystalXY->SetFillColor(fcCrystalHL);
00327 fCrystalXY->SetFillStyle(fsCrystalHL);
00328 }
00329 if (fCrystalXYFired) {
00330 fCrystalXYFired->SetLineColor(lcCrystalFiredHL);
00331 fCrystalXYFired->SetLineWidth(lwCrystalFiredHL);
00332 fCrystalXYFired->SetFillColor(fcCrystalFiredHL);
00333 fCrystalXYFired->SetFillStyle(fsCrystalFiredHL);
00334 }
00335 }
00336
00337 if ( fCrystalXY && IsXYVisible() ) fCrystalXY->Paint();
00338 if (this->IsFired()) {
00339 if (view->GetVisEmcHitsGlobal() &&
00340 ( (fPart == 0 && view->GetVisEmcHitsEast()) ||
00341 (fPart == 1 && view->GetVisEmcHitsBarrel()) ||
00342 (fPart == 2 && view->GetVisEmcHitsWest()) )) {
00343 if (fCrystalXYFired) {
00344 fCrystalXY->Paint();
00345
00346
00347 fCrystalXYFired->Restore();
00348 fCrystalXYFired->SetSize(fCharge/fChargeMax);
00349 fCrystalXYFired->Paint();
00350 }
00351 }
00352 }
00353 }
00354
00355 if (view->GetViewType() & kZRView) {
00356 if (HasZRSection()) {
00357 if (this->IsFired()) {
00358 if (fCrystalZRFired) {
00359 fCrystalZRFired->SetLineColor(lcCrystalFired);
00360 fCrystalZRFired->SetLineWidth(lwCrystalFired);
00361 fCrystalZRFired->SetFillColor(fcCrystalFired);
00362 fCrystalZRFired->SetFillStyle(fsCrystalFired);
00363 }
00364 }
00365
00366 if (fCrystalZR) {
00367 fCrystalZR->SetLineColor(lcCrystal);
00368 fCrystalZR->SetLineWidth(lwCrystal);
00369 fCrystalZR->SetFillColor(fcCrystal);
00370 fCrystalZR->SetFillStyle(fsCrystal);
00371 }
00372
00373 if (this->IsHighlighted()) {
00374 if (fCrystalZR) {
00375 fCrystalZR->SetLineColor(lcCrystalHL);
00376 fCrystalZR->SetLineWidth(lwCrystalHL);
00377 fCrystalZR->SetFillColor(fcCrystalHL);
00378 fCrystalZR->SetFillStyle(fsCrystalHL);
00379 }
00380 if (fCrystalZRFired) {
00381 fCrystalZRFired->SetLineColor(lcCrystalFiredHL);
00382 fCrystalZRFired->SetLineWidth(lwCrystalFiredHL);
00383 fCrystalZRFired->SetFillColor(fcCrystalFiredHL);
00384 fCrystalZRFired->SetFillStyle(fsCrystalFiredHL);
00385 }
00386 }
00387
00388 if ( fCrystalZR ) fCrystalZR->Paint();
00389 if (this->IsFired()) {
00390 if (view->GetVisEmcHitsGlobal() &&
00391 ( (fPart == 0 && view->GetVisEmcHitsEast()) ||
00392 (fPart == 1 && view->GetVisEmcHitsBarrel()) ||
00393 (fPart == 2 && view->GetVisEmcHitsWest()) )) {
00394 if (fCrystalZRFired) {
00395
00396 fCrystalZRFired->Restore();
00397 fCrystalZRFired->SetSize(fCharge/fChargeMax);
00398 fCrystalZRFired->Paint();
00399 }
00400 }
00401 }
00402 }
00403
00404
00405 if (this->IsFired()) {
00406 if (fCrystalSideFired) {
00407 fCrystalSideFired->SetLineColor(lcCrystalFired);
00408 fCrystalSideFired->SetLineWidth(lwCrystalFired);
00409 fCrystalSideFired->SetFillColor(fcCrystalFired);
00410 fCrystalSideFired->SetFillStyle(fsCrystalFired);
00411 }
00412 }
00413
00414 if (fCrystalSide) {
00415 fCrystalSide->SetLineColor(lcCrystal);
00416 fCrystalSide->SetLineWidth(lwCrystal);
00417 fCrystalSide->SetFillColor(fcCrystal);
00418 fCrystalSide->SetFillStyle(fsCrystal);
00419 }
00420
00421 if (this->IsHighlighted()) {
00422 if (fCrystalSide) {
00423 fCrystalSide->SetLineColor(lcCrystalHL);
00424 fCrystalSide->SetLineWidth(lwCrystalHL);
00425 fCrystalSide->SetFillColor(fcCrystalHL);
00426 fCrystalSide->SetFillStyle(fsCrystalHL);
00427 }
00428 if (fCrystalSideFired) {
00429 fCrystalSideFired->SetLineColor(lcCrystalFiredHL);
00430 fCrystalSideFired->SetLineWidth(lwCrystalFiredHL);
00431 fCrystalSideFired->SetFillColor(fcCrystalFiredHL);
00432 fCrystalSideFired->SetFillStyle(fsCrystalFiredHL);
00433 }
00434 }
00435
00436 if ( IsSideVisible() ) {
00437 if ( (view->GetVisEmcSide() || view->GetVisEmcHitsSide() && this->IsFired()) && fCrystalSide ) fCrystalSide->Paint();
00438 if ( this->IsFired() ) {
00439 if (view->GetVisEmcHitsGlobal() && view->GetVisEmcHitsSide()) {
00440 if (fCrystalSideFired) {
00441
00442 fCrystalSideFired->Restore();
00443 fCrystalSideFired->SetSize(fCharge/fChargeMax);
00444 fCrystalSideFired->Paint();
00445 }
00446 }
00447 }
00448 }
00449 }
00450 }
00451
00452
00453
00454 char *Emc2DCrystal::GetObjectInfo(Int_t px, Int_t py) const {
00455
00456 BesView *view = (BesView*)gPad->GetView();
00457 if (view) return view->GetObjectInfo(px, py);
00458 else return TObject::GetObjectInfo(px, py);
00459 }
00460
00461
00462
00463 bool Emc2DCrystal::HasZRSection()
00464 {
00465 bool flag = false;
00466 BesView *view = (BesView*)gPad->GetView();
00467 Double_t viewPhi = view->GetLongitude();
00468 viewPhi = Range360(viewPhi);
00469
00470
00471 Double_t zrPhi = viewPhi-90.0;
00472 zrPhi = Range360(zrPhi);
00473
00474
00475 for (Int_t i = 0; i < 2; i++) {
00476 if (i==1) {
00477 zrPhi += 180.0;
00478 zrPhi = Range360(zrPhi);
00479 }
00480
00481 if (zrPhi >= fPhiMin-fZRSectionTolerance[GetPart()] &&
00482 zrPhi <= fPhiMax+fZRSectionTolerance[GetPart()]) {
00483 flag = true;
00484 break;
00485 }
00486 else if (fPhiMin > fPhiMax) {
00487
00488 if (zrPhi >= fPhiMin-fZRSectionTolerance[GetPart()] ||
00489 zrPhi <= fPhiMax+fZRSectionTolerance[GetPart()]) {
00490 flag = true;
00491 break;
00492 }
00493 }
00494 }
00495
00496 return flag;
00497 }
00498
00499
00500
00501 Double_t Emc2DCrystal::GetAngle(Double_t x, Double_t y)
00502 {
00503 Double_t angle = TMath::ACos( x/TMath::Sqrt(x*x+y*y) ) * TMath::RadToDeg();
00504 if ( y<0.0 ) angle *= -1;
00505 angle = Range360(angle);
00506
00507 return angle;
00508 }
00509
00510
00511
00512 Double_t Emc2DCrystal::Range360(Double_t input)
00513 {
00514 if (input >= 360.0) {
00515 do {
00516 input -= 360.0;
00517 }
00518 while (input >= 360.0);
00519 }
00520 else if (input < 0.0) {
00521 do {
00522 input += 360.0;
00523 }
00524 while (input < 0.0);
00525 }
00526
00527 return input;
00528 }
00529
00530 bool Emc2DCrystal::IsXYVisible()
00531 {
00532 if ( GetPart() != 1 || GetTheta() == 0 || IsFired() )
00533 return true;
00534 else
00535 return false;
00536 }
00537
00538 bool Emc2DCrystal::IsSideVisible()
00539 {
00540 BesView *view = (BesView*)gPad->GetView();
00541 Double_t viewPhi = view->GetLongitude();
00542 Double_t viewPhiMin = viewPhi - sideDeltaPhi;
00543 Double_t viewPhiMax = viewPhi + sideDeltaPhi;
00544
00545 viewPhi = Range360(viewPhi);
00546 viewPhiMin = Range360(viewPhiMin);
00547 viewPhiMax = Range360(viewPhiMax);
00548
00549
00550 if (viewPhiMin < viewPhiMax) {
00551 if (fPhiMax > viewPhiMin && fPhiMax < viewPhiMax) return true;
00552 }
00553 else {
00554 if (fPhiMax > viewPhiMin || fPhiMax < viewPhiMax) return true;
00555 }
00556
00557 return false;
00558 }
00559
00560
00561
00562 void Emc2DCrystal::SetXYPoint(Double_t *p1, Double_t *p2, Double_t *newP, Double_t z)
00563 {
00564 Double_t ratio = fabs( (z-p1[2]) / (p2[2]-p1[2]) );
00565 for (Int_t i = 0; i < 3; i++) {
00566 newP[i] = p1[i] * (1.0-ratio) + p2[i] * ratio;
00567 }
00568 }
00569
00570
00571
00572 void Emc2DCrystal::SetZRPoint(Double_t *p1, Double_t *p2, Double_t *newP, Double_t r)
00573 {
00574 Double_t r1 = sqrt(p1[0]*p1[0] + p1[1]*p1[1]);
00575 Double_t r2 = sqrt(p2[0]*p2[0] + p2[1]*p2[1]);
00576
00577 Double_t ratio = fabs( (r-r1) / (r2-r1) );
00578 for (Int_t i = 0; i < 3; i++) {
00579 newP[i] = p1[i] * (1.0-ratio) + p2[i] * ratio;
00580 }
00581 }
00582
00583 void Emc2DCrystal::ProjectECToSide(Double_t *p1, Double_t *newP)
00584 {
00585
00586
00587
00588
00589 Double_t r1 = sqrt(p1[0]*p1[0] + p1[1]*p1[1]);
00590 newP[0] = p1[0] * (brZRPointR/r1);
00591 newP[1] = p1[1] * (brZRPointR/r1);
00592
00593 Double_t drToR = brZRPointR - r1;
00594 newP[2] = fabs(ecXYPointZ + drToR) * (p1[2]/fabs(p1[2]));
00595
00596
00597
00598
00599
00600
00601
00602 }