Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 2 // See the file tools.license for terms. 3 4 #ifndef tools_hplot 5 #define tools_hplot 6 7 // Used in tools::sg::axis. 8 // 9 // Code extracted from ROOT-4.03.02/root/graf/ 10 // Itself built from code extracted from HPLOT 11 // 12 // Take care, all the below is highly disgusti 13 // (You can even find.. gotos !) 14 // 15 // Except for the public methods we let the st 16 17 #include "mnmx" 18 #include "lina/vec3f" 19 #include "mathd" //pi 20 #include "snpf" 21 #include "out_error" 22 23 #include <string> 24 #include <vector> 25 26 #include <cstring> 27 #include <ctime> 28 #include <cmath> 29 #include <cfloat> 30 31 namespace tools { 32 namespace hplot { 33 34 class _text { 35 public: 36 _text(double aX,double aY, 37 double aAngle,double aSize, 38 const std::string& aString, 39 short aAlign) 40 :fX(aX),fY(aY) 41 ,fAngle(aAngle),fSize(aSize) 42 ,fString(aString),fAlign(aAlign) 43 {} 44 virtual ~_text(){} 45 public: 46 _text(const _text& aFrom) 47 :fX(aFrom.fX),fY(aFrom.fY) 48 ,fAngle(aFrom.fAngle),fSize(aFrom.fSize) 49 ,fString(aFrom.fString) 50 ,fAlign(aFrom.fAlign) 51 {} 52 _text& operator=(const _text& aFrom){ 53 fX = aFrom.fX; 54 fY = aFrom.fY; 55 fAngle = aFrom.fAngle; 56 fSize = aFrom.fSize; 57 fString = aFrom.fString; 58 fAlign = aFrom.fAlign; 59 return *this; 60 } 61 public: 62 double fX; 63 double fY; 64 double fAngle; //Degree 65 double fSize; 66 std::string fString; 67 short fAlign; 68 }; 69 70 71 class axis { 72 73 // Ok, you really want to read all that. You 74 75 enum { 76 TAxis_kTickPlus = (1<<(9)), 77 TAxis_kTickMinus = (1<<(10)), 78 TAxis_kAxisRange = (1<<(11)), 79 TAxis_kCenterTitle = (1<<(12)), 80 TAxis_kCenterLabels = (1<<(14)), //bit 13 81 TAxis_kRotateTitle = (1<<(15)), 82 TAxis_kPalette = (1<<(16)), 83 TAxis_kNoExponent = (1<<(17)), 84 TAxis_kLabelsHori = (1<<(18)), 85 TAxis_kLabelsVert = (1<<(19)), 86 TAxis_kLabelsDown = (1<<(20)), 87 TAxis_kLabelsUp = (1<<(21)), 88 TAxis_kIsInteger = (1<<(22)), 89 TAxis_kMoreLogLabels = (1<<(23)), 90 TAxis_kDecimals = (1<<(11)) 91 }; //in fBits2 92 93 enum { 94 kIsOnHeap = 0x01000000, // object 95 kNotDeleted = 0x02000000, // object 96 kZombie = 0x04000000, // object 97 kBitMask = 0x00ffffff 98 }; 99 100 static int GetTextFont() { return 132;} 101 102 static double TMath_ATan2(double y, double x 103 if (x != 0) return ::atan2(y, x); 104 if (y == 0) return 0; 105 if (y > 0) return half_pi(); 106 else return -half_pi(); 107 } 108 109 //static short TMath_Abs(short d) { return 110 static int TMath_Abs(int d) { return (d >= 0 111 //static long TMath_Abs(long d) { return (d 112 //static float TMath_Abs(float d) { return ( 113 static double TMath_Abs(double d) { return ( 114 115 static void TGaxis_Rotate( 116 double X, double Y, double CFI, double SF 117 ,double XT, double YT, double &U, double & 118 { 119 U = CFI*X-SFI*Y+XT; 120 V = SFI*X+CFI*Y+YT; 121 } 122 123 public: 124 axis(std::ostream& a_out) 125 :m_out(a_out) 126 //,fMaxDigits(5) 127 ,fBits(kNotDeleted) 128 ,fTickSize(0.03F) 129 ,fLabelOffset(0.005F) 130 ,fLabelSize(0.04F) 131 ,fTitleOffset(1) 132 ,fTitleSize(0.04F) 133 ,fLabelFont(62) 134 {} 135 136 virtual ~axis(){} 137 private: //to discourage inheriting that. 138 axis(const axis& a_from):m_out(a_from.m_out) 139 axis& operator=(const axis&){return *this;} 140 public: 141 void set_title(const std::string& aTitle) { 142 fTitle = aTitle; 143 } 144 private: 145 bool testBit(unsigned int f) { 146 return (bool) ((fBits & f) != 0); 147 } 148 149 static void TGaxis_LabelsLimits(std::ostream 150 int & 151 last = int(::strlen(label))-1; 152 for (int i=0; i<=last; i++) { 153 if (::strchr("1234567890-+.", label[i]) 154 } 155 out_error(a_out,"LabelsLimits", "attempt t 156 } 157 static void SETOPT(const std::string& aCHOPT 158 aOpt = aCHOPT.find(aChar)!=std::string::np 159 } 160 161 public: 162 void paint(double xmin, double ymin, 163 double xmax, double ymax, 164 double& wmin,double& wmax, 165 int& ndiv,const std::strin 166 double gridlength,bool dra 167 std::vector<float>& aLines 168 std::vector<float>& aLines 169 std::vector<_text>& aTexts 170 // Control function to draw an axis 171 // ================================ 172 // 173 //============> Original authors (O.Couet 174 // largely modified and conve 175 // 176 // _Input parameters: 177 // 178 // xmin : X origin coordinate in WC 179 // xmax : X end axis coordinate in W 180 // ymin : Y origin coordinate in WC 181 // ymax : Y end axis coordinate in W 182 // wmin : Lowest value for the tick 183 // labels written on the axis 184 // wmax : Highest value for the tick 185 // written on the axis. 186 // ndiv : Number of divisions. 187 // 188 // ndiv=N1 + 100*N2 + 10000*N3 189 // N1=number of 1st divisions. 190 // N2=number of 2nd divisions. 191 // N3=number of 3rd divisions. 192 // e.g.: 193 // nndi=0 --> no tick marks. 194 // nndi=2 --> 2 divisions, one t 195 // of the axis. 196 // 197 // chopt : Options (see below). 198 // 199 // chopt='G': loGarithmic scale, def 200 // chopt='B': Blank axis. Useful to 201 // 202 // Orientation of tick marks on axis. 203 // ---------------------------------- 204 // 205 // Tick marks are normally drawn on the 206 // however, if X0=X1, then negative. 207 // 208 // chopt='+': tick marks are drawn o 209 // chopt='-': tick mark are drawn on 210 // i.e: '+-' --> tick marks are draw 211 // chopt='U': Unlabeled axis, defaul 212 // 213 // Size of tick marks 214 // ------------------ 215 // By default, tick marks have a length eq 216 // axis length. 217 // When the option "S" is specified, the l 218 // is equal to fTickSize*axis_length, wher 219 // via TGaxis::SetTickSize. 220 // 221 // Position of labels on axis. 222 // --------------------------- 223 // 224 // Labels are normally drawn on side opp 225 // However: 226 // 227 // chopt='=': on Equal side 228 // 229 // Orientation of labels on axis. 230 // ------------------------------ 231 // 232 // Labels are normally drawn parallel to 233 // However if X0=X1, then Orthogonal 234 // if Y0=Y1, then Parallel 235 // 236 // Position of labels on tick marks. 237 // --------------------------------- 238 // 239 // Labels are centered on tick marks. 240 // However , if X0=X1, then they are rig 241 // 242 // chopt='R': labels are Right adjus 243 // (default is centered 244 // chopt='L': labels are Left adjust 245 // chopt='C': labels are Centered on 246 // chopt='M': In the Middle of the d 247 // 248 // Format of labels. 249 // ----------------- 250 // 251 // Blank characters are stripped, and th 252 // label is correctly aligned. the dot, 253 // character of the string, is also stri 254 // unless the option "." (a dot, or peri 255 // if SetDecimals(true) has been called 256 // all labels have the same number of de 257 // The same is true if gStyle->SetStripD 258 // 259 // In the following, we have some parame 260 // tick marks length and characters heig 261 // of the length of the axis (WC)) 262 // The default values are as follows: 263 // 264 // Primary tick marks: 3.0 % 265 // Secondary tick marks: 1.5 % 266 // Third order tick marks: .75 % 267 // Characters height for labels: 4% 268 // 269 // Labels offset: 1.0 % 270 // 271 // Optional grid. 272 // -------------- 273 // 274 // chopt='W': cross-Wire 275 // In case of a log axis, the grid is on 276 // tick marks if the number of secondary 277 // 278 // Axis bining optimization. 279 // ------------------------- 280 // 281 // By default the axis bining is optimiz 282 // 283 // chopt='N': No bining optimization 284 // chopt='I': Integer labelling 285 // 286 // Maximum Number of Digits for the axis l 287 // --------------------------------------- 288 // See the static function TGaxis::SetMaxD 289 // 290 // Time representation. 291 // -------------------- 292 // 293 // Axis labels may be considered as time 294 // time format. 295 // The format is set with SetTimeFormat( 296 // wmin and wmax are considered as two t 297 // The time axis will be spread around t 298 // SetTimeOffset() ). Actually it will g 299 // TimeOffset+wmax. 300 // see examples in tutorials timeonaxis. 301 // 302 // chopt='t': Plot times with a defi 303 // 304 305 aLinesAxis.clear(); 306 aLinesGrid.clear(); 307 aTexts.clear(); 308 309 double alfa, beta, ratio1, ratio2, grid_s 310 double axis_lengthN = 0; 311 double axis_length0 = 0; 312 double axis_length1 = 0; 313 double charheight; 314 double phil, phi, sinphi, cosphi, asinphi 315 double BinLow, BinLow2, BinLow3; 316 double BinHigh, BinHigh2, BinHigh3; 317 double BinWidth, BinWidth2, BinWidth3; 318 double xpl1, xpl2, ypl1, ypl2; 319 double Xtick = 0; 320 double Xtick0, Xtick1, DXtick=0; 321 double Ytick, Ytick0, Ytick1; 322 double Wlabel, DWlabel; 323 double Xlabel, Ylabel; 324 double DXlabel; 325 double X0, X1, Y0, Y1, XX0, XX1, YY0, YY1 326 XX0 = XX1 = YY0 = YY1 = 0; 327 double Xxmin, Xxmax, Yymin, Yymax; 328 Xxmin = Xxmax = Yymin = Yymax = 0; 329 double XLside,XMside; 330 double WW, AF, RNE; 331 double XX, YY; 332 double Y; 333 double Xtwo; 334 int i, j, k, l, decade, ltick; 335 int Mside, Lside; 336 int IF1, IF2, NA, NF, NCH; 337 int OptionLog,OptionBlank,OptionVert,Opti 338 int OptionUnlab,OptionPara; 339 int OptionDown,OptionRight,OptionLeft,Opt 340 int OptionDecimals=0,OptionDot; 341 int OptionY,OptionText,OptionGrid,OptionS 342 int OptionInt,OptionM,OptionUp,OptionX; 343 int OptionTime; 344 int first,last; 345 int nbins; 346 int N1Aold = 0; 347 int NN1old = 0; 348 int Xalign,Yalign; 349 int ndyn; 350 char LABEL[256]; 351 char CHTEMP[256]; 352 double rangeOffset = 0; 353 354 double epsilon = 1e-5; 355 const double kPI = pi(); //GB 356 double textSize = 0.05; //GB 357 short textAlign = 11; //GB 358 BinWidth = 0; //GB 359 BinWidth2 = 0; //GB 360 BinWidth3 = 0; //GB 361 nbins = 0; //GB 362 BinHigh = 0; //GB 363 BinHigh2 = 0; //GB 364 BinHigh3 = 0; //GB 365 BinLow = 0; //GB 366 BinLow2 = 0; //GB 367 BinLow3 = 0; //GB 368 first = 0; //GB 369 last = 0; //GB 370 371 double rwmi = wmin; 372 double rwma = wmax; 373 374 //out_error(m_out,"android_debug","start" 375 376 bool noExponent = testBit(TAxis_kNoExpone 377 378 // If MoreLogLabels = true more Log Inter 379 bool MoreLogLabels = testBit(TAxis_kMoreL 380 381 // the following parameters correspond to 382 // and the WC coordinates in the pad 383 384 double padh = 1;//FIXME gPad->GetWh()*g 385 double RWxmin = 0; 386 double RWxmax = 1; 387 double RWymin = 0; 388 double RWymax = 1; 389 390 SETOPT(aCHOPT,'G',OptionLog); 391 SETOPT(aCHOPT,'B',OptionBlank); 392 SETOPT(aCHOPT,'V',OptionVert); 393 SETOPT(aCHOPT,'+',OptionPlus); 394 SETOPT(aCHOPT,'-',OptionMinus); 395 SETOPT(aCHOPT,'U',OptionUnlab); 396 SETOPT(aCHOPT,'P',OptionPara); 397 SETOPT(aCHOPT,'O',OptionDown); 398 SETOPT(aCHOPT,'R',OptionRight); 399 SETOPT(aCHOPT,'L',OptionLeft); 400 SETOPT(aCHOPT,'C',OptionCent); 401 SETOPT(aCHOPT,'=',OptionEqual); 402 SETOPT(aCHOPT,'Y',OptionY); 403 SETOPT(aCHOPT,'T',OptionText); 404 SETOPT(aCHOPT,'W',OptionGrid); 405 SETOPT(aCHOPT,'S',OptionSize); 406 SETOPT(aCHOPT,'N',OptionNoopt); 407 SETOPT(aCHOPT,'I',OptionInt); 408 SETOPT(aCHOPT,'M',OptionM); 409 SETOPT(aCHOPT,'0',OptionUp); 410 SETOPT(aCHOPT,'X',OptionX); 411 SETOPT(aCHOPT,'t',OptionTime); 412 SETOPT(aCHOPT,'.',OptionDot); 413 414 if (testBit(TAxis_kTickPlus)) OptionP 415 if (testBit(TAxis_kTickMinus)) OptionM 416 if (testBit(TAxis_kCenterLabels)) OptionM 417 if (testBit(TAxis_kDecimals)) OptionD 418 /*FIXME if (fAxis) { 419 if (fAxis->GetLabels()) { 420 OptionM = 1; 421 OptionText = 1; 422 ndiv = fAxis->GetLast()-fAxis->GetF 423 } 424 }*/ 425 426 // Set the grid length 427 428 if (OptionGrid) { 429 if (gridlength == 0) gridlength = 0.8; 430 /*FIXME 431 linegrid = new TLine(); 432 linegrid->SetLineColor(gStyle->GetGrid 433 if (linegrid->GetLineColor() == 0) 434 linegrid->SetLineColor(GetLineColor( 435 linegrid->SetLineStyle(gStyle->GetGrid 436 linegrid->SetLineWidth(gStyle->GetGrid 437 } 438 439 440 if (OptionTime) { 441 //printf("debug : SbAxisHPLOT::paint : 442 // fTimeFormat.c_str()); 443 } 444 445 //out_error(m_out,"android_debug","0000") 446 // Determine time format 447 std::string timeformat; 448 std::string::size_type IdF = fTimeFormat. 449 if (IdF!=std::string::npos) { 450 timeformat = fTimeFormat.substr(0,IdF); 451 } else { 452 timeformat = fTimeFormat; 453 } 454 455 //out_error(m_out,"android_debug","0001") 456 // determine the time offset and correct 457 double timeoffset = 0; 458 if (OptionTime) { 459 if (IdF!=std::string::npos) { 460 int LnF = int(fTimeFormat.size()); 461 std::string stringtimeoffset = fTim 462 int yy, mm, dd, hh, mi, ss; 463 if (::sscanf(stringtimeoffset.c_str 464 "%d-%d-%d %d:%d:%d", &yy, & 465 struct tm tp; 466 struct tm* tptest; 467 time_t timeoffsettest; 468 tp.tm_year = yy-1900; 469 tp.tm_mon = mm-1; 470 tp.tm_mday = dd; 471 tp.tm_hour = hh; 472 tp.tm_min = mi; 473 tp.tm_sec = ss; 474 tp.tm_isdst = 0; // daylight sav 475 timeoffset = double(mktime(&tp) 476 // have to correct this time to 477 timeoffsettest = (time_t)((long) 478 tptest = gmtime(&timeoffsettest) 479 timeoffset += timeoffsettest - m 480 // Add the time offset's decimal 481 std::string::size_type Ids = s 482 if (Ids != std::string::npos) { 483 float dp; 484 size_t Lns = stringtimeoffs 485 std::string sdp = stringtimeo 486 ::sscanf(sdp.c_str(),"%g",&dp 487 timeoffset += dp; 488 } 489 // if OptionTime = 2 gmtime will be 490 if (stringtimeoffset.find("GMT") 491 OptionTime =2; 492 } else { 493 out_error(m_out,"PaintAxis", "Ti 494 } 495 } else { 496 out_error(m_out,"PaintAxis", "%%F 497 //FIXME timeoffset = gStyle->GetT 498 } 499 wmin += timeoffset - (int)(timeoffse 500 wmax += timeoffset - (int)(timeoffse 501 // correct for time offset at a good 502 // day, month, year) 503 struct tm* tp0; 504 time_t timetp = (time_t)((long)(time 505 double range = wmax - wmin; 506 long rangeBase = 60; 507 if (range>60) rangeBase = 60*2 508 if (range>3600) rangeBase = 3600 509 if (range>86400) rangeBase = 8640 510 if (range>2419200) rangeBase = 3155 511 rangeOffset = (double) ((long)(timeo 512 if (range>31536000) { 513 tp0 = gmtime(&timetp); 514 tp0->tm_mon = 0; 515 tp0->tm_mday = 1; 516 tp0->tm_hour = 0; 517 tp0->tm_min = 0; 518 tp0->tm_sec = 0; 519 tp0->tm_isdst = 0; // daylight sav 520 rangeBase = long(timetp-mktime(tp0 521 rangeOffset = (double) (rangeBase) 522 } 523 wmax += rangeOffset; 524 wmin += rangeOffset; 525 } 526 527 // Determine number of divisions 1, 2 and 528 int N1A = ndiv%100; 529 int N2A = (ndiv%10000 - N1A)/100; 530 int N3A = ndiv/10000; 531 int NN3 = mx<int>(N3A,1); 532 int NN2 = mx<int>(N2A,1)*NN3; 533 int NN1 = mx<int>(N1A,1)*NN2+1; 534 int Nticks= NN1; 535 536 // Axis bining optimization is ignored if 537 // - the first and the last label are equ 538 // - the number of divisions is 0 539 // - less than 1 primary division is requ 540 // - logarithmic scale is requested 541 542 if (wmin == wmax || ndiv == 0 || N1A <= 1 543 OptionNoopt = 1; 544 OptionInt = 0; 545 } 546 547 // Axis bining optimization 548 if ( (wmax-wmin) < 1 && OptionInt) { 549 out_error(m_out,"PaintAxis", "option I 550 OptionInt = 0; 551 } 552 //out_error(m_out,"android_debug","0002") 553 if (!OptionNoopt || OptionInt ) { 554 555 // Primary divisions optimization 556 // When integer labelling is required, 557 // and only if the result is not an in 558 // is invoked. 559 560 optimizeLimits(wmin,wmax,N1A, 561 BinLow,BinHigh,nbins,Bi 562 aCHOPT); 563 if (OptionInt) { 564 if (BinLow != double(int(BinLow)) | 565 BinWidth != double(int(BinWidth 566 adjustBinSize(wmin,wmax,N1A,BinL 567 } 568 } 569 if ((wmin-BinLow) > epsilon) { BinLow 570 if ((BinHigh-wmax) > epsilon) { BinHig 571 if (xmax == xmin) { 572 double rtyw = (ymax-ymin)/(wmax-wm 573 Xxmin = xmin; 574 Xxmax = xmax; 575 Yymin = rtyw*(BinLow-wmin) + ymin; 576 Yymax = rtyw*(BinHigh-wmin) + ymin; 577 } else { 578 double rtxw = (xmax-xmin)/(wmax-wm 579 Xxmin = rtxw*(BinLow-wmin) + xmin; 580 Xxmax = rtxw*(BinHigh-wmin) + xmin; 581 if (ymax == ymin) { 582 Yymin = ymin; 583 Yymax = ymax; 584 } else { 585 alfa = (ymax-ymin)/(xmax-xmin); 586 beta = (ymin*xmax-ymax*xmin)/(x 587 Yymin = alfa*Xxmin + beta; 588 Yymax = alfa*Xxmax + beta; 589 } 590 } 591 /*GB if (fFunction) { 592 Yymin = ymin; 593 Yymax = ymax; 594 Xxmin = xmin; 595 Xxmax = xmax; 596 } else*/ { 597 wmin = BinLow; 598 wmax = BinHigh; 599 } 600 601 // Secondary divisions optimization 602 int NB2 = N2A; 603 if (!OptionNoopt && N2A > 1 && BinWidt 604 optimizeLimits(wmin,wmin+BinWidth,N 605 BinLow2,BinHigh2,NB2 606 aCHOPT); 607 } 608 609 // Tertiary divisions optimization 610 int NB3 = N3A; 611 if (!OptionNoopt && N3A > 1 && BinWidt 612 optimizeLimits(BinLow2,BinLow2+BinW 613 BinLow3,BinHigh3,NB3 614 aCHOPT); 615 } 616 N1Aold = N1A; 617 NN1old = NN1; 618 N1A = nbins; 619 NN3 = mx<int>(NB3,1); 620 NN2 = mx<int>(NB2,1)*NN3; 621 NN1 = mx<int>(N1A,1)*NN2+1; 622 Nticks = NN1; 623 } 624 625 //out_error(m_out,"android_debug","0003") 626 // Coordinates are normalized 627 628 ratio1 = 1/(RWxmax-RWxmin); 629 ratio2 = 1/(RWymax-RWymin); 630 X0 = ratio1*(xmin-RWxmin); 631 X1 = ratio1*(xmax-RWxmin); 632 Y0 = ratio2*(ymin-RWymin); 633 Y1 = ratio2*(ymax-RWymin); 634 if (!OptionNoopt || OptionInt ) { 635 XX0 = ratio1*(Xxmin-RWxmin); 636 XX1 = ratio1*(Xxmax-RWxmin); 637 YY0 = ratio2*(Yymin-RWymin); 638 YY1 = ratio2*(Yymax-RWymin); 639 } 640 641 //out_error(m_out,"android_debug","0004") 642 if ((X0 == X1) && (Y0 == Y1)) { 643 out_error(m_out,"PaintAxis", "length o 644 return; 645 } 646 647 // Return wmin, wmax and the number of pr 648 if (OptionX) { 649 ndiv = N1A; 650 return; 651 } 652 653 int maxDigits = 5; 654 //FIXME if (fAxis) maxDigits = fMaxDigits 655 656 /*FIXME 657 TLatex *textaxis = new TLatex(); 658 lineaxis->SetLineColor(GetLineColor()); 659 lineaxis->SetLineStyle(1); 660 lineaxis->SetLineWidth(GetLineWidth()); 661 textaxis->SetTextColor(GetTextColor()); 662 textaxis->SetTextFont(GetTextFont()); 663 664 if (!gPad->IsBatch()) { 665 float chupxvsav, chupyvsav; 666 gVirtualX->GetCharacterUp(chupxvsav, c 667 gVirtualX->SetClipOFF(gPad->GetCanvasI 668 } 669 */ 670 671 // Compute length of axis 672 double axis_length = ::sqrt((X1-X0)*(X1-X 673 if (axis_length == 0) { 674 out_error(m_out,"PaintAxis", "length o 675 return; //goto L210; 676 } 677 678 //out_error(m_out,"android_debug","0005") 679 if (!OptionNoopt || OptionInt) { 680 axis_lengthN = ::sqrt((XX1-XX0)*(XX1-X 681 axis_length0 = ::sqrt((XX0-X0)*(XX0-X0 682 axis_length1 = ::sqrt((X1-XX1)*(X1-XX1 683 if (axis_lengthN < epsilon) { 684 OptionNoopt = 1; 685 OptionInt = 0; 686 wmin = rwmi; 687 wmax = rwma; 688 N1A = N1Aold; 689 NN1 = NN1old; 690 Nticks = NN1; 691 if (OptionTime) { 692 wmin += timeoffset - (int 693 wmax += timeoffset - (int 694 } 695 } 696 } 697 698 //out_error(m_out,"android_debug","0006") 699 if (X0 == X1) { 700 phi = 0.5*kPI; 701 phil = phi; 702 } else { 703 phi = TMath_ATan2((Y1-Y0),(X1-X0 704 int px0 = 0;//FIXME gPad->UtoPixel(X0) 705 int py0 = 0;//FIXME gPad->VtoPixel(Y0) 706 int px1 = 0;//FIXME gPad->UtoPixel(X1) 707 int py1 = 0;//FIXME gPad->VtoPixel(Y1) 708 if (X0 < X1) phil = TMath_ATan2(double 709 else phil = TMath_ATan2(double 710 } 711 cosphi = ::cos(phi); 712 sinphi = ::sin(phi); 713 acosphi = TMath_Abs(cosphi); 714 asinphi = TMath_Abs(sinphi); 715 if (acosphi <= epsilon) { acosphi = 0; c 716 if (asinphi <= epsilon) { asinphi = 0; s 717 718 //out_error(m_out,"android_debug","0007") 719 // Mside positive, tick marks on positive 720 // Mside negative, tick marks on negative 721 // Mside zero, tick marks on both sides 722 // Default is positive except for vertica 723 724 Mside=1; 725 if (X0 == X1 && Y1 > Y0) Mside = -1 726 if (OptionPlus) Mside = 1; 727 if (OptionMinus) Mside = -1 728 if (OptionPlus && OptionMinus) Mside = 0; 729 XMside = Mside; 730 Lside = -Mside; 731 if (OptionEqual) Lside = Mside; 732 if (OptionPlus && OptionMinus) { 733 Lside = -1; 734 if (OptionEqual) Lside=1; 735 } 736 XLside = Lside; 737 738 // Tick marks size 739 double tick_side; 740 if(XMside >= 0) tick_side = 1; 741 else tick_side = -1; 742 743 double atick[3]; 744 if (OptionSize) atick[0] = tick_side*axis 745 else atick[0] = tick_side*axis 746 747 atick[1] = 0.5*atick[0]; 748 atick[2] = 0.5*atick[1]; 749 750 // Set the side of the grid 751 if ((X0 == X1) && (Y1 > Y0)) grid_side = 752 else grid_side = 753 754 755 //out_error(m_out,"android_debug","0008") 756 // Compute Values if Function is given 757 /*GB if(fFunction) { 758 rwmi = fFunction->Eval(wmin); 759 rwma = fFunction->Eval(wmax); 760 if(rwmi > rwma) { 761 double t = rwma; 762 rwma = rwmi; 763 rwmi = t; 764 } 765 }*/ 766 767 // Draw the axis if needed... 768 if (!OptionBlank) { 769 xpl1 = X0; 770 xpl2 = X1; 771 ypl1 = Y0; 772 ypl2 = Y1; 773 aLinesAxis.push_back((float)xpl1); 774 aLinesAxis.push_back((float)ypl1); 775 aLinesAxis.push_back((float)xpl2); 776 aLinesAxis.push_back((float)ypl2); 777 } 778 779 //out_error(m_out,"android_debug","0009") 780 // No bining 781 782 if (ndiv == 0) return; //goto L210; 783 if (wmin == wmax) { 784 out_error(m_out,"PaintAxis", "wmin (%f 785 return; //goto L210; 786 } 787 788 // Draw axis title if it exists 789 if (!drawGridOnly && fTitle.size()) { 790 textSize = fTitleSize; 791 charheight = fTitleSize; 792 if ((GetTextFont() % 10) > 2) { 793 //FIXME charheight = charheight/gPa 794 } 795 double toffset = fTitleOffset; 796 if (toffset < 0.1) toffset = 1; 797 if (X1 == X0) Ylabel = XLside*1.6*char 798 else Ylabel = XLside*1.3*char 799 if (Y1 == Y0) Ylabel = XLside*1.6*char 800 double axispos; 801 if (testBit(TAxis_kCenterTitle)) axisp 802 else axispos = a 803 if (testBit(TAxis_kRotateTitle)) { 804 if (X1 >= X0) { 805 if (testBit(TAxis_kCenterTitle)) 806 else 807 TGaxis_Rotate(axispos,Ylabel,cos 808 } else { 809 if (testBit(TAxis_kCenterTitle)) 810 else 811 TGaxis_Rotate(axispos,Ylabel,cosp 812 } 813 out_error(m_out,"PaintAxis","debug 814 aTexts.push_back(_text(xpl1,ypl1, 815 p 816 f 817 f 818 } else { 819 if (X1 >= X0) { 820 if (testBit(TAxis_kCenterTitle)) 821 else 822 TGaxis_Rotate(axispos,Ylabel,cos 823 } else { 824 if (testBit(TAxis_kCenterTitle)) 825 else 826 TGaxis_Rotate(axispos,Ylabel,cosp 827 } 828 aTexts.push_back(_text(xpl1,ypl1, 829 p 830 f 831 } 832 } 833 834 //out_error(m_out,"android_debug","0010") 835 // Labels preparation: 836 // Get character height 837 // Compute the labels orientation in case 838 // with alphanumeric labels for horizonta 839 840 charheight = fLabelSize; 841 if (OptionText) charheight *= 0.66666; 842 //FIXME textaxis->SetTextFont(fLabelFont) 843 //FIXME textaxis->SetTextColor(GetLabelCo 844 textSize = charheight; 845 //FIXME textaxis->SetTextAngle(GetTextAng 846 if (fLabelFont%10 > 2) { 847 charheight /= padh; 848 } 849 if (!OptionUp && !OptionDown && !OptionY) 850 if (!drawGridOnly && OptionText && ((y 851 textAlign = 32; 852 OptionText = 2; 853 //int nl = 0;//FIXME fAxis->GetLast 854 //double angle = 0; 855 out_error(m_out,"PaintAxis","debug 856 /*FIXME 857 for (i=fAxis->GetFirst(); i<=fAxis- 858 textaxis->SetText(0,0,fAxis->Get 859 if (textaxis->GetXsize() < (xmax 860 angle = -20; 861 break; 862 } 863 for (i=fAxis->GetFirst(); i<=fAxis- 864 if ((!::strcmp(fAxis->GetName(), 865 ||(!::strcmp(fAxis->GetName(), 866 if (nl > 50) angle = 90; 867 if (fAxis->testBit(TAxis_kLab 868 if (fAxis->testBit(TAxis_kLab 869 if (fAxis->testBit(TAxis_kLab 870 if (fAxis->testBit(TAxis_kLab 871 if (angle== 0) textAlign = 872 if (angle== -20) textAlign = 873 out_error(m_out,"PaintAxis"," 874 textaxis->PaintLatex( 875 fAxis->GetBinCenter(i), 876 gPad->GetUymin() - 3*fAxis- 877 (gPad->GetUymax()-gPad->G 878 angle, 879 charheight, 880 fAxis->GetBinLabel(i)); 881 } else if ((!::strcmp(fAxis->Get 882 || (!::strcmp(fAxis->Get 883 out_error(m_out,"PaintAxis"," 884 textaxis->PaintLatex( 885 gPad->GetUxmin() - 3*fAxis- 886 (gPad->GetUxmax()-gPad->G 887 fAxis->GetBinCenter(i), 888 0, 889 charheight, 890 fAxis->GetBinLabel(i)); 891 } else { 892 out_error(m_out,"PaintAxis"," 893 textaxis->PaintLatex( 894 xmin - 3*fAxis->GetLabelOff 895 (gPad->GetUxmax()-gPad->G 896 ymin +(i-0.5)*(ymax-ymin)/n 897 0, 898 charheight, 899 fAxis->GetBinLabel(i)); 900 } 901 }*/ 902 } 903 } 904 905 //out_error(m_out,"android_debug","0011") 906 // Now determine orientation of labels on 907 /*FIXME 908 if (!gPad->IsBatch()) { 909 if (cosphi > 0) gVirtualX->SetCharacte 910 else gVirtualX->SetCharacte 911 if (X0 == X1) gVirtualX->SetCharacte 912 if (OptionVert) gVirtualX->SetCharacte 913 if (OptionPara) gVirtualX->SetCharacte 914 if (OptionDown) gVirtualX->SetCharacte 915 }*/ 916 917 // Now determine text alignment 918 Xalign = 2; 919 Yalign = 1; 920 if (X0 == X1) Xalign = 3; 921 if (Y0 != Y1) Yalign = 2; 922 if (OptionCent) Xalign = 2; 923 if (OptionRight) Xalign = 3; 924 if (OptionLeft) Xalign = 1; 925 if (TMath_Abs(cosphi) > 0.9) { 926 Xalign = 2; 927 } else { 928 if (cosphi*sinphi > 0) Xalign = 1; 929 if (cosphi*sinphi < 0) Xalign = 3; 930 } 931 textAlign = 10*Xalign+Yalign; 932 933 //out_error(m_out,"android_debug","0012") 934 // Position of labels in Y 935 if (X0 == X1) { 936 if (OptionPlus && !OptionMinus) { 937 if (OptionEqual) Ylabel = fLabelOf 938 else Ylabel = -fLabelOf 939 } else { 940 Ylabel = fLabelOffset; 941 if (Lside < 0) Ylabel += atick[0]; 942 } 943 } else if (Y0 == Y1) { 944 if (OptionMinus && !OptionPlus) { 945 Ylabel = fLabelOffset+0.5*fLabelSiz 946 Ylabel += TMath_Abs(atick[0]); 947 } else { 948 Ylabel = -fLabelOffset; 949 if (Mside <= 0) Ylabel -= TMath_Abs 950 } 951 if (OptionLog) Ylabel -= 0.5*charheig 952 } else { 953 if (Mside+Lside >= 0) Ylabel = fLabel 954 else Ylabel = -fLabel 955 } 956 if (OptionText) Ylabel /= 2; 957 958 //out_error(m_out,"android_debug","0013") 959 // Draw the linear tick marks if needed.. 960 if (!OptionLog) { 961 if (ndiv) { 962 /*GB if (fFunction) { 963 if (OptionNoopt && !OptionInt) { 964 DXtick=(BinHigh-BinLow)/doubl 965 } else { 966 DXtick=(BinHigh-BinLow)/doubl 967 } 968 } else */ { 969 if (OptionNoopt && !OptionInt) D 970 else D 971 } 972 for (k=0;k<Nticks; k++) { 973 ltick = 2; 974 if (k%NN3 == 0) ltick = 1; 975 if (k%NN2 == 0) ltick = 0; 976 /*GB if (fFunction) { 977 double xx = BinLow+double(k)* 978 double zz = fFunction->Eval(x 979 Xtick = zz* axis_length / TMa 980 } else */ { 981 Xtick = double(k)*DXtick; 982 } 983 Ytick = 0; 984 if (!Mside) Ytick -= atick[ltick 985 if ( OptionNoopt && !OptionInt) 986 TGaxis_Rotate(Xtick,Ytick,cos 987 TGaxis_Rotate(Xtick,atick[lti 988 } 989 else { 990 TGaxis_Rotate(Xtick,Ytick,cos 991 TGaxis_Rotate(Xtick,atick[lti 992 } 993 if (OptionVert) { 994 if ((X0 != X1) && (Y0 != Y1)) 995 if (Mside) { 996 xpl1 = xpl2; 997 if (cosphi > 0) ypl1 = 998 else ypl1 = 999 } 1000 else { 1001 xpl1 = 0.5*(xpl1 + xpl 1002 xpl2 = xpl1; 1003 ypl1 = 0.5*(ypl1 + ypl 1004 ypl2 = 0.5*(ypl1 + ypl 1005 } 1006 } 1007 } 1008 if (!drawGridOnly) { 1009 aLinesAxis.push_back((float)x 1010 aLinesAxis.push_back((float)y 1011 aLinesAxis.push_back((float)x 1012 aLinesAxis.push_back((float)y 1013 } 1014 1015 if (OptionGrid) { 1016 if (ltick == 0) { 1017 if (OptionNoopt && !Optio 1018 TGaxis_Rotate(Xtick,0,c 1019 TGaxis_Rotate 1020 (Xtick,grid_side*grid 1021 xpl1,ypl1); 1022 } else { 1023 TGaxis_Rotate(Xtick,0,c 1024 TGaxis_Rotate 1025 (Xtick,grid_side*grid 1026 xpl1,ypl1); 1027 } 1028 aLinesGrid.push_back((flo 1029 aLinesGrid.push_back((flo 1030 aLinesGrid.push_back((flo 1031 aLinesGrid.push_back((flo 1032 } 1033 } 1034 } 1035 Xtick0 = 0; 1036 Xtick1 = Xtick; 1037 1038 if ((!OptionNoopt || OptionInt) && 1039 int Nticks0; 1040 /*GB if (fFunction) Nticks0 = i 1041 else */ Nticks0 = int( 1042 if (Nticks0 > 1000) Nticks0 = 1 1043 for (k=0; k<=Nticks0; k++) { 1044 ltick = 2; 1045 if (k%NN3 == 0) ltick = 1; 1046 if (k%NN2 == 0) ltick = 0; 1047 Ytick0 = 0; 1048 if (!Mside) Ytick0 -= atick[ 1049 /*GB if (fFunction) { 1050 Xtick0 = (fFunction->Eval 1051 * axis_length / 1052 }*/ 1053 TGaxis_Rotate(Xtick0,Ytick0, 1054 TGaxis_Rotate(Xtick0,atick[l 1055 if (OptionVert) { 1056 if ((X0 != X1) && (Y0 != 1057 if (Mside) { 1058 xpl1 = xpl2; 1059 if (cosphi > 0) ypl 1060 else ypl 1061 } 1062 else { 1063 xpl1 = 0.5*(xpl1 + 1064 xpl2 = xpl1; 1065 ypl1 = 0.5*(ypl1 + 1066 ypl2 = 0.5*(ypl1 + 1067 } 1068 } 1069 } 1070 if(!drawGridOnly) { 1071 aLinesAxis.push_back((floa 1072 aLinesAxis.push_back((floa 1073 aLinesAxis.push_back((floa 1074 aLinesAxis.push_back((floa 1075 } 1076 1077 if (OptionGrid) { 1078 if (ltick == 0) { 1079 TGaxis_Rotate(Xtick0,0, 1080 TGaxis_Rotate 1081 (Xtick0,grid_side*gri 1082 xpl1,ypl1); 1083 aLinesGrid.push_back((f 1084 aLinesGrid.push_back((f 1085 aLinesGrid.push_back((f 1086 aLinesGrid.push_back((f 1087 } 1088 } 1089 Xtick0 -= DXtick; 1090 } 1091 } 1092 1093 if ((!OptionNoopt || OptionInt) && 1094 int Nticks1; 1095 /*GB if (fFunction) Nticks1 = i 1096 else */ Nticks1 = int( 1097 if (Nticks1 > 1000) Nticks1 = 1 1098 for (k=0; k<=Nticks1; k++) { 1099 ltick = 2; 1100 if (k%NN3 == 0) ltick = 1; 1101 if (k%NN2 == 0) ltick = 0; 1102 Ytick1 = 0; 1103 if (!Mside) Ytick1 -= atick[ 1104 /*GB if (fFunction) { 1105 Xtick1 = (fFunction->Eval 1106 * axis_length / 1107 }*/ 1108 TGaxis_Rotate(Xtick1,Ytick1, 1109 TGaxis_Rotate(Xtick1,atick[l 1110 if (OptionVert) { 1111 if ((X0 != X1) && (Y0 != 1112 if (Mside) { 1113 xpl1 = xpl2; 1114 if (cosphi > 0) ypl 1115 else ypl 1116 } 1117 else { 1118 xpl1 = 0.5*(xpl1 + 1119 xpl2 = xpl1; 1120 ypl1 = 0.5*(ypl1 + 1121 ypl2 = 0.5*(ypl1 + 1122 } 1123 } 1124 } 1125 if(!drawGridOnly) { 1126 aLinesAxis.push_back((floa 1127 aLinesAxis.push_back((floa 1128 aLinesAxis.push_back((floa 1129 aLinesAxis.push_back((floa 1130 } 1131 1132 if (OptionGrid) { 1133 if (ltick == 0) { 1134 TGaxis_Rotate(Xtick1,0, 1135 TGaxis_Rotate 1136 (Xtick1,grid_side*gri 1137 xpl1,ypl1); 1138 aLinesGrid.push_back((f 1139 aLinesGrid.push_back((f 1140 aLinesGrid.push_back((f 1141 aLinesGrid.push_back((f 1142 } 1143 } 1144 Xtick1 += DXtick; 1145 } 1146 } 1147 } 1148 } 1149 1150 //out_error(m_out,"android_debug","0014" 1151 // Draw the numeric labels if needed... 1152 if (!drawGridOnly && !OptionUnlab) { 1153 if (!OptionLog) { 1154 if (N1A) { 1155 // Spacing of labels 1156 if ((wmin == wmax) || (ndiv == 1157 out_error(m_out,"PaintAxis", 1158 return; //goto L210; 1159 } 1160 Wlabel = wmin; 1161 DWlabel = (wmax-wmin)/double(N1 1162 if (OptionNoopt && !OptionInt) 1163 else 1164 1165 char CHCODED[8]; 1166 int NEXE = 0; 1167 bool FLEXE = false; 1168 if (!OptionText && !OptionTime) 1169 1170 // We have to decide what fo 1171 // for numeric labels only) 1172 // Test the magnitude, decid 1173 FLEXE = false; 1174 NEXE = 0; 1175 bool FLEXPO = false; 1176 bool FLEXNE = false; 1177 WW = mx<double>(TMath_Abs(w 1178 1179 // First case : (wmax-wmin)/ 1180 // 0.001 fMaxDigits of 5 (fM 1181 // Then we use x 10 n 1182 // format. If AF >=0 x10 n c 1183 double xmicros = 0.00099; 1184 if (maxDigits) xmicros = ::p 1185 if (!noExponent && (TMath_Ab 1186 AF = ::log10(WW) + eps 1187 if (AF < 0) { 1188 FLEXE = true; 1189 NEXE = int(AF); 1190 int IEXE = TMath_Abs( 1191 if (IEXE%3 == 1) I 1192 else if(IEXE%3 == 2) I 1193 if (NEXE < 0) NEXE = - 1194 else NEXE = 1195 Wlabel = Wlabel*::pow 1196 DWlabel = DWlabel*::po 1197 IF1 = maxDigits; 1198 IF2 = maxDigits-2; 1199 goto L110; 1200 } 1201 } 1202 if (WW >= 1) AF = ::log10(WW 1203 else AF = ::log10(WW 1204 AF += epsilon; 1205 NF = int(AF)+1; 1206 if (!noExponent && NF > maxD 1207 if (!noExponent && NF < -max 1208 1209 // Use x 10 n format. (only 1210 1211 if (FLEXPO) { 1212 FLEXE = true; 1213 while (1) { 1214 NEXE++; 1215 WW /= 10; 1216 Wlabel /= 10; 1217 DWlabel /= 10; 1218 if (NEXE%3 == 0 && WW 1219 } 1220 } 1221 1222 if (FLEXNE) { 1223 FLEXE = true; 1224 RNE = 1/::pow(10.,maxDi 1225 while (1) { 1226 NEXE--; 1227 WW *= 10; 1228 Wlabel *= 10; 1229 DWlabel *= 10; 1230 if (NEXE%3 == 0 && WW 1231 } 1232 } 1233 1234 NA = 0; 1235 for (i=maxDigits-1; i>0; i-- 1236 if (TMath_Abs(WW) < ::pow 1237 } 1238 ndyn = N1A; 1239 while (ndyn) { 1240 double wdyn = TMath_Abs(( 1241 if (wdyn <= 0.999 && NA < 1242 NA++; 1243 ndyn /= 10; 1244 } 1245 else break; 1246 } 1247 1248 IF2 = NA; 1249 IF1 = mx<int>(NF+NA,maxDigit 1250 L110: 1251 if (mn<double>(wmin,wmax) < 1252 IF1 = mn<int>(IF1,32); 1253 1254 // In some cases, IF1 and IF 1255 while (DWlabel < ::pow(10.,- 1256 IF1++; 1257 IF2++; 1258 } 1259 //char* CODED = &CHCODED[0]; 1260 if (IF1 > 14) IF1=14; 1261 if (IF2 > 14) IF2=14; 1262 if(IF2)snpf(CHCODED,sizeof(C 1263 else snpf(CHCODED,sizeof(C 1264 } 1265 1266 // We draw labels 1267 1268 snpf(CHTEMP,sizeof(CHTEMP),"%g" 1269 1270 size_t ndecimals = 0; 1271 if (OptionDecimals) { 1272 char *dot = ::strchr(CHTEMP, 1273 if (dot) ndecimals = CHTEMP 1274 } 1275 int Nlabels; 1276 if (OptionM) Nlabels = N1A-1; 1277 else Nlabels = N1A; 1278 double wTimeIni = Wlabel; 1279 for ( k=0; k<=Nlabels; k++) { 1280 /*FIXME if (fFunction) { 1281 double xx = BinLow+double 1282 double zz = fFunction->Ev 1283 Wlabel = xx; 1284 Xlabel = zz* axis_length 1285 } else */{ 1286 Xlabel = DXlabel*k; 1287 } 1288 if (OptionM) Xlabel += 0. 1289 1290 if (!OptionText && !OptionTi 1291 snpf(LABEL,sizeof(LABEL), 1292 LABEL[28] = 0; 1293 Wlabel += DWlabel; 1294 1295 TGaxis_LabelsLimits(m_out 1296 1297 if (LABEL[first] == '.') 1298 ::strcpy(CHTEMP, "0"); 1299 ::strcat(CHTEMP, &LABE 1300 ::strcpy(LABEL, CHTEMP 1301 first = 1; last = int( 1302 } 1303 if (LABEL[first] == '-' & 1304 ::strcpy(CHTEMP, "-0") 1305 ::strcat(CHTEMP, &LABE 1306 ::strcpy(LABEL, CHTEMP 1307 first = 1; last = int( 1308 } 1309 1310 // We eliminate the non s 1311 if (ndecimals) { 1312 char *adot = ::strchr( 1313 if (adot) adot[ndecima 1314 } else { 1315 while (LABEL[last] == 1316 } 1317 // We eliminate the dot, 1318 if (LABEL[last] == '.') { 1319 if (!OptionDot) { LABE 1320 } 1321 } 1322 1323 // Generate the time labels 1324 1325 if (OptionTime) { 1326 double timed = Wlabel + ( 1327 time_t timelabel = (time_ 1328 struct tm* utctis; 1329 if (OptionTime == 1) { 1330 utctis = localtime(&ti 1331 } else { 1332 utctis = gmtime(&timel 1333 } 1334 std::string timeformattmp 1335 if (timeformat.size() < 2 1336 else timeformattmp = "#sp 1337 1338 // Appends fractionnal pa 1339 if (DWlabel<0.9) { 1340 double tmpdb; 1341 size_t tmplast; 1342 snpf(LABEL,sizeof(LABE 1343 tmplast = ::strlen(LAB 1344 1345 // We eliminate the no 1346 while (LABEL[tmplast] 1347 LABEL[tmplast] = 0; 1348 } 1349 1350 //FIXME timeformattmp. 1351 // Replace the "0." at 1352 //FIXME timeformattmp. 1353 1354 } 1355 1356 ::strftime(LABEL,256,time 1357 ::strcpy(CHTEMP,&LABEL[0] 1358 first = 0; last=int(::str 1359 Wlabel = wTimeIni + (k+1) 1360 } 1361 1362 // We generate labels (numer 1363 1364 if (OptionNoopt && !OptionIn 1365 TGaxis_Rotate (Xlab 1366 else TGaxis_Rotate (Xlab 1367 if (Y0 == Y1 && !OptionDown 1368 YY -= 0.80*charheight; 1369 } 1370 if (OptionVert) { 1371 if (X0 != X1 && Y0 != Y1) 1372 if (OptionNoopt && !Op 1373 TGaxis_Rotate (X 1374 else TGaxis_Rotate (X 1375 if (cosphi > 0 ) YY += 1376 if (cosphi < 0 ) YY -= 1377 } 1378 } 1379 if (!OptionY || (X0 == X1)) 1380 if (!OptionText) { 1381 if (first > last) ::s 1382 else ::s 1383 aTexts.push_back(_text 1384 1385 1386 } 1387 else { 1388 if (OptionText == 1) { 1389 out_error(m_out,"Pai 1390 /*textaxis->PaintLat 1391 (gPad->GetX1() + X 1392 gPad->GetY1() + Y 1393 0, 1394 textaxis->GetText 1395 fAxis->GetBinLabe 1396 } 1397 } 1398 } 1399 else { 1400 1401 // Text alignment is down 1402 int LNLEN = 0; 1403 if (!OptionText) LNLE 1404 else { 1405 int NHILAB = 0; 1406 if (k+1 > NHILAB) LNLE 1407 } 1408 for ( l=1; l<=LNLEN; l++) 1409 if (!OptionText) *CHTE 1410 else { 1411 if (LNLEN == 0) ::s 1412 else ::s 1413 } 1414 aTexts.push_back(_text 1415 1416 1417 YY -= charheight*1.3; 1418 } 1419 } 1420 } 1421 1422 // We use the format x 10 ** n 1423 1424 if (FLEXE && !OptionText && NEX 1425 //G.Barrand ::sprintf(LABEL, 1426 snpf(LABEL,sizeof(LABEL), 1427 "x10^%d!", NEXE); //G.B 1428 double Xfactor, Yfactor; 1429 if (X0 != X1) { Xfactor = X1 1430 else { Xfactor = Y1 1431 TGaxis_Rotate (Xfactor,Yfact 1432 textAlign = 11; 1433 aTexts.push_back(_text(XX,YY 1434 1435 1436 } 1437 } 1438 } 1439 } 1440 1441 // Log axis 1442 1443 //out_error(m_out,"android_debug","0015" 1444 if (OptionLog && ndiv) { 1445 unsigned int xi1=0,xi2 = 0,wi = 0,yi1 1446 bool firstintlab = true, overlap = fa 1447 if ((wmin == wmax) || (ndiv == 0)) { 1448 out_error(m_out,"PaintAxis", "wmin 1449 return; //goto L210; 1450 } 1451 if (wmin <= 0) { 1452 out_error(m_out,"PaintAxis", "nega 1453 return; //goto L210; 1454 } 1455 if (wmax <= 0) { 1456 out_error(m_out,"PaintAxis", "nega 1457 return; //goto L210; 1458 } 1459 double XMNLOG = ::log10(wmin); 1460 if (XMNLOG > 0) XMNLOG += 1.E-6; 1461 else XMNLOG -= 1.E-6; 1462 double X00 = 0; 1463 double X11 = axis_length; 1464 double H2 = ::log10(wmax); 1465 double H2SAV = H2; 1466 if (H2 > 0) H2 += 1.E-6; 1467 else H2 -= 1.E-6; 1468 int IH1 = int(XMNLOG); 1469 int IH2 = 1+int(H2); 1470 int NBININ = IH2-IH1+1; 1471 double AXMUL = (X11-X00)/(H2SAV-XMNL 1472 1473 // Plot decade and intermediate tick 1474 decade = IH1-2; 1475 int labelnumber = IH1; 1476 if ( XMNLOG > 0 && (XMNLOG-double(IH1 1477 for (j=1; j<=NBININ; j++) { 1478 1479 // Plot decade 1480 firstintlab = true, overlap = fals 1481 decade++; 1482 if (X0 == X1 && j == 1) Ylabel += 1483 if (Y0 == Y1 && j == 1) Ylabel -= 1484 double Xone = X00+AXMUL*(double(de 1485 //the following statement is a tri 1486 //GB if (j < 0) ::printf("j=%d\n", 1487 if (X00 > Xone) goto L160; 1488 if (Xone > X11) break; 1489 Xtwo = Xone; 1490 Y = 0; 1491 if (!Mside) Y -= atick[0]; 1492 TGaxis_Rotate(Xone,Y,cosphi,sinphi 1493 TGaxis_Rotate(Xtwo,atick[0],cosphi 1494 if (OptionVert) { 1495 if ((X0 != X1) && (Y0 != Y1)) { 1496 if (Mside) { 1497 xpl1=xpl2; 1498 if (cosphi > 0) ypl1 = yp 1499 else ypl1 = yp 1500 } 1501 else { 1502 xpl1 = 0.5*(xpl1 + xpl2); 1503 xpl2 = xpl1; 1504 ypl1 = 0.5*(ypl1 + ypl2) 1505 ypl2 = 0.5*(ypl1 + ypl2) 1506 } 1507 } 1508 } 1509 if (!drawGridOnly) { 1510 aLinesAxis.push_back((float)xpl1 1511 aLinesAxis.push_back((float)ypl1 1512 aLinesAxis.push_back((float)xpl2 1513 aLinesAxis.push_back((float)ypl2 1514 } 1515 1516 if (OptionGrid) { 1517 TGaxis_Rotate(Xone,0,cosphi,sinp 1518 TGaxis_Rotate(Xone,grid_side*gri 1519 xpl1,ypl1); 1520 aLinesGrid.push_back((float)xpl1 1521 aLinesGrid.push_back((float)ypl1 1522 aLinesGrid.push_back((float)xpl2 1523 aLinesGrid.push_back((float)ypl2 1524 } 1525 1526 if (!drawGridOnly && !OptionUnlab) 1527 1528 // We generate labels (numeric 1529 if (noExponent) { 1530 double rlab = ::pow(10.,labe 1531 snpf(LABEL,sizeof(LABEL), "% 1532 TGaxis_LabelsLimits(m_out,LA 1533 while (last > first) { 1534 if (LABEL[last] != '0') b 1535 LABEL[last] = 0; 1536 last--; 1537 } 1538 if (LABEL[last] == '.') {LAB 1539 } else { 1540 snpf(LABEL,sizeof(LABEL), "% 1541 TGaxis_LabelsLimits(m_out,LA 1542 } 1543 TGaxis_Rotate (Xone,Ylabel,cosp 1544 if ((X0 == X1) && !OptionPara) 1545 if (Lside < 0) { 1546 if (Mside < 0) { 1547 if (labelnumber == 0) 1548 else 1549 XX += NCH*charheigh 1550 } else { 1551 if (labelnumber >= 0) 1552 else 1553 } 1554 } 1555 XX += 0.25*charheight; 1556 } 1557 if ((Y0 == Y1) && !OptionDown & 1558 if (noExponent) YY += 0.33*c 1559 } 1560 if (N1A == 0) return; //goto L2 1561 int KMOD = NBININ/N1A; 1562 if (KMOD == 0) KMOD=1000000; 1563 if ((NBININ <= N1A) || (j == 1) 1564 && (j%KMOD == 0))) { 1565 if (labelnumber == 0) { 1566 aTexts.push_back(_text(XX 1567 1568 1569 } else if (labelnumber == 1) 1570 aTexts.push_back(_text(XX 1571 1572 1573 } else { 1574 if (noExponent) { 1575 out_error(m_out,"PaintA 1576 //FIXME textaxis->Paint 1577 } else { 1578 //FIXME : support CERN- 1579 // ::sprintf(CHTEMP, " 1580 snpf(CHTEMP,sizeof(CHTE 1581 "10^%d?", labelnum 1582 aTexts.push_back(_text( 1583 1584 1585 } 1586 } 1587 } 1588 labelnumber++; 1589 } 1590 L160: 1591 for (k=2;k<10;k++) { 1592 1593 // Plot intermediate tick marks 1594 //double Xone; //rm shadow warn 1595 Xone = X00+AXMUL*(::log10(doubl 1596 if (X00 > Xone) continue; 1597 if (Xone > X11) goto L200; 1598 Y = 0; 1599 if (!Mside) Y -= atick[1]; 1600 Xtwo = Xone; 1601 TGaxis_Rotate(Xone,Y,cosphi,sin 1602 TGaxis_Rotate(Xtwo,atick[1],cos 1603 if (OptionVert) { 1604 if ((X0 != X1) && (Y0 != Y1) 1605 if (Mside) { 1606 xpl1 = xpl2; 1607 if (cosphi > 0) ypl1 = 1608 else ypl1 = 1609 } 1610 else { 1611 xpl1 = 0.5*(xpl1+xpl2) 1612 xpl2 = xpl1; 1613 ypl1 = 0.5*(ypl1+ypl2) 1614 ypl2 = 0.5*(ypl1+ypl2) 1615 } 1616 } 1617 } 1618 int IDN = N1A*2; 1619 if ((NBININ <= IDN) || ((NBININ 1620 if(!drawGridOnly) { 1621 aLinesAxis.push_back((floa 1622 aLinesAxis.push_back((floa 1623 aLinesAxis.push_back((floa 1624 aLinesAxis.push_back((floa 1625 } 1626 1627 // Draw the intermediate LOG 1628 1629 if (MoreLogLabels && !Option 1630 !drawGridOnly && !overla 1631 if (noExponent) { 1632 double rlab = double(k 1633 snpf(CHTEMP,sizeof(CHT 1634 } else { 1635 if (labelnumber-1 == 0 1636 snpf(CHTEMP,sizeof( 1637 } else if (labelnumber 1638 snpf(CHTEMP,sizeof( 1639 } else { 1640 //G.Barrand : 1641 //::sprintf(CHTEMP, 1642 snpf(CHTEMP,sizeof(CHTEMP 1643 "%dx10^%d!",k,la 1644 } 1645 } 1646 TGaxis_Rotate (Xone,Ylabe 1647 if ((Y0 == Y1) && !Option 1648 if (noExponent) YY += 1649 } 1650 if (X0 == X1) XX += 0.25* 1651 if (OptionVert) { 1652 if ((X0 != X1) && (Y0 1653 TGaxis_Rotate(Xone, 1654 if (cosphi > 0) YY 1655 else YY 1656 } 1657 } 1658 //FIXME textaxis->SetTitl 1659 double u = XX; 1660 double v = YY; 1661 if (firstintlab) { 1662 //FIXME textaxis->GetB 1663 xi1 = 0;//FIXME gPad-> 1664 yi1 = 0;//FIXME gPad-> 1665 firstintlab = false; 1666 out_error(m_out,"Paint 1667 aTexts.push_back(_text 1668 1669 1670 } else { 1671 xi2 = 0;//FIXME gPad-> 1672 yi2 = 0;//FIXME gPad-> 1673 if ((X0 == X1 && yi1-h 1674 overlap = true; 1675 } else { 1676 xi1 = xi2; 1677 yi1 = yi2; 1678 //FIXME textaxis->G 1679 out_error(m_out,"Pa 1680 aTexts.push_back(_t 1681 1682 1683 } 1684 } 1685 } 1686 1687 // Draw the intermediate LOG 1688 // decades are requested 1689 if (OptionGrid && NBININ <= 1690 TGaxis_Rotate(Xone,0,cosph 1691 TGaxis_Rotate 1692 (Xone,grid_side*gridleng 1693 aLinesGrid.push_back((floa 1694 aLinesGrid.push_back((floa 1695 aLinesGrid.push_back((floa 1696 aLinesGrid.push_back((floa 1697 } 1698 } //endif ((NBININ <= IDN) || 1699 } //endfor (k=2;k<10;k++) 1700 } //endfor (j=1; j<=NBININ; j++) 1701 L200: 1702 int kuku=0; if (kuku) { } 1703 } //endif (OptionLog && ndiv) 1704 1705 1706 //out_error(m_out,"android_debug","end") 1707 //L210: 1708 } 1709 1710 /* 1711 void TGaxis_SetDecimals(bool dot) 1712 { 1713 // Set the Decimals flag 1714 // By default, blank characters are strippe 1715 // label is correctly aligned. The dot, if 1716 // is also stripped, unless this option is 1717 // One can disable the option by calling ax 1718 // Note the bit is set in fBits (as opposed 1719 1720 if (dot) SetBit(TAxis_kDecimals); 1721 else ResetBit(TAxis_kDecimals); 1722 } 1723 1724 void TGaxis_SetMaxDigits(int maxd) 1725 { 1726 // static function to set fMaxDigits for 1727 // (y axis for 1-d histogram, z axis for 1728 //fMaxDigits is the maximum number of di 1729 //labels above which the notation with 1 1730 //For example, to accept 6 digits number 1731 //call TGaxis::SetMaxDigits(6). The defa 1732 //fMaxDigits must be greater than 0. 1733 1734 fMaxDigits = maxd; 1735 if (maxd < 1) fMaxDigits = 1; 1736 } 1737 1738 void TGaxis_SetMoreLogLabels(bool more) 1739 { 1740 // Set the kMoreLogLabels bit flag 1741 // When this option is selected more labels 1742 // and there is a small number of decades 1743 // Note that this option is automatically i 1744 1745 if (more) SetBit(TAxis_kMoreLogLabels); 1746 else ResetBit(TAxis_kMoreLogLabels) 1747 } 1748 void TGaxis_SetNoExponent(bool noExponent) 1749 { 1750 // Set the NoExponent flag 1751 // By default, an exponent of the form 10^N 1752 // are either all very small or very large. 1753 // One can disable the exponent by calling 1754 1755 if (noExponent) SetBit(TAxis_kNoExponent 1756 else ResetBit(TAxis_kNoExpone 1757 } 1758 void TGaxis_SetOption(const std::string& op 1759 { 1760 fCHOPT = option; 1761 } 1762 */ 1763 1764 void set_time_format(const std::string& a_f 1765 // Change the format used for time plotting 1766 // ======================================== 1767 // The format string for date and time use 1768 // in the standard strftime C function, i. 1769 // for date : 1770 // %a abbreviated weekday name 1771 // %b abbreviated month name 1772 // %d day of the month (01-31) 1773 // %m month (01-12) 1774 // %y year without century 1775 // 1776 // for time : 1777 // %H hour (24-hour clock) 1778 // %I hour (12-hour clock) 1779 // %p local equivalent of AM or PM 1780 // %M minute (00-59) 1781 // %S seconds (00-61) 1782 // %% % 1783 // 1784 { 1785 if (a_format.find("%F")!=std::string::np 1786 fTimeFormat = a_format; 1787 //::printf("debug : SbAxisHPLOT::setT 1788 // fTimeFormat.c_str()); 1789 return; 1790 } 1791 1792 std::string::size_type IdF = fTimeFormat 1793 if (IdF!=std::string::npos) { 1794 size_t LnF = fTimeFormat.size(); 1795 std::string stringtimeoffset = fTimeF 1796 fTimeFormat = a_format; 1797 fTimeFormat += stringtimeoffset; 1798 //::printf("debug : SbAxisHPLOT::setT 1799 // fTimeFormat.c_str()); 1800 } else { 1801 fTimeFormat = a_format; 1802 1803 // In CERN-ROOT : 1804 //SetTimeOffset(gStyle->GetTimeOffset 1805 //TAxis::fTimeOffset = 788918400; // 1806 //double UTC_time_1995_01_01__00_00_0 1807 //setTimeOffset(UTC_time_1995_01_01__ 1808 1809 //Be consistent with SoAxis::timeOffs 1810 double UTC_time_1970_01_01__00_00_00 1811 set_time_offset(UTC_time_1970_01_01__ 1812 1813 //::printf("debug : SbAxisHPLOT::setT 1814 // fTimeFormat.c_str()); 1815 } 1816 } 1817 1818 void set_time_offset(double toffset,bool a_ 1819 // Change the time offse t 1820 1821 std::string::size_type IdF = fTimeFormat 1822 if (IdF!=std::string::npos) { 1823 fTimeFormat = fTimeFormat.substr(0,IdF 1824 } 1825 fTimeFormat += "%F"; 1826 1827 time_t timeoff = (time_t)((long)(toffset 1828 struct tm* utctis = ::gmtime(&timeoff); 1829 1830 char tmp[256]; 1831 ::strftime(tmp,256,"%Y-%m-%d %H:%M:%S",u 1832 fTimeFormat += tmp; 1833 1834 // append the decimal part of the time o 1835 double ds = toffset-(int)toffset; 1836 if(ds!= 0) { 1837 snpf(tmp,sizeof(tmp),"s%g",ds); 1838 fTimeFormat += tmp; 1839 } 1840 1841 // If the time is GMT, stamp fTimeFormat 1842 if (a_is_gmt) fTimeFormat += " GMT"; 1843 1844 //::printf("debug : SbAxisHPLOT::setTime 1845 // fTimeFormat.c_str()); 1846 } 1847 1848 1849 1850 /////////////////////////////////////////// 1851 /////////////////////////////////////////// 1852 /////////////////////////////////////////// 1853 private: 1854 static void optimizeLimits( 1855 double A1,double A2,int nold 1856 ,double &BinLow, double &BinHigh 1857 ,int &nbins, double &BinWidth 1858 ,const std::string& aCHOPT 1859 ){ 1860 // static function to compute reasonable ax 1861 // 1862 // Input parameters: 1863 // 1864 // A1,A2 : Old WMIN,WMAX . 1865 // BinLow,BinHigh : New WMIN,WMAX . 1866 // nold : Old NDIV . 1867 // nbins : New NDIV . 1868 1869 int lwid, kwid; 1870 int ntemp = 0; 1871 int jlog = 0; 1872 double siground = 0; 1873 double alb, awidth, sigfig; 1874 double timemulti = 1; 1875 int roundmode =0; 1876 1877 int OptionTime; 1878 SETOPT(aCHOPT,'t',OptionTime); 1879 1880 double AL = mn<double>(A1,A2); 1881 double AH = mx<double>(A1,A2); 1882 if (AL == AH) AH = AL+1; 1883 // if nold == -1 , program uses binwid 1884 if (nold == -1 && BinWidth > 0 ) goto L9 1885 ntemp = (int)mx<double>(nold,2); 1886 if (ntemp < 1) ntemp = 1; 1887 1888 L20: 1889 awidth = (AH-AL)/double(ntemp); 1890 timemulti = 1; 1891 if (awidth >= FLT_MAX) goto LOK; //in f 1892 if (awidth <= 0) goto LOK; 1893 1894 // If time representation, bin width s 1895 // minutes, hours or days 1896 1897 if (OptionTime && awidth>=60) { // if wi 1898 // width in minutes 1899 awidth /= 60; timemulti *=60; 1900 roundmode = 1; // round minutes (60) 1901 // width in hours ? 1902 if (awidth>=60) { 1903 awidth /= 60; timemulti *= 60; 1904 roundmode = 2; // round hours (24) 1905 // width in days ? 1906 if (awidth>=24) { 1907 awidth /= 24; timemulti *= 24; 1908 roundmode = 3; // round days (3 1909 // width in months ? 1910 if (awidth>=30.43685) { // Mean 1911 awidth /= 30.43685; timemult 1912 roundmode = 2; // round mont 1913 // width in years ? 1914 if (awidth>=12) { 1915 awidth /= 12; timemulti * 1916 roundmode = 0; // round y 1917 } 1918 } 1919 } 1920 } 1921 } 1922 // Get nominal bin width in exponentia 1923 1924 jlog = int(::log10(awidth)); 1925 if (jlog <-200 || jlog > 200) { 1926 BinLow = 0; 1927 BinHigh = 1; 1928 BinWidth = 0.01; 1929 nbins = 100; 1930 return; 1931 } 1932 if (awidth <= 1 && (!OptionTime || timem 1933 sigfig = awidth* ::pow(10.,-jlog) -1e-10 1934 //in the above statement, it is importan 1935 //to avoid precision problems if the tes 1936 1937 // Round mantissa 1938 1939 switch (roundmode) { 1940 1941 // Round mantissa up to 1, 1.5, 2, 3, 1942 case 1: // case 60 1943 if (sigfig <= 1) siground 1944 else if (sigfig <= 1.5 && jlog==1) 1945 else if (sigfig <= 2) siground 1946 else if (sigfig <= 3 && jlog ==1) 1947 else if (sigfig <= 5 && sigfig>3 & 1948 else if (jlog==0) {siground 1949 else siground 1950 break; 1951 case 2: // case 12 and 24 1952 1953 // Round mantissa up to 1, 1.2, 2, 2.4 1954 if (sigfig <= 1 && jlog==0) 1955 else if (sigfig <= 1.2 && jlog==1) 1956 else if (sigfig <= 2 && jlog==0) 1957 else if (sigfig <= 2.4 && jlog==1) 1958 else if (sigfig <= 3) siground 1959 else if (sigfig <= 6) siground 1960 else if (jlog==0) siground 1961 else siground 1962 break; 1963 1964 //- Round mantissa up to 1, 1.4, 2, or 1965 case 3: // case 30 1966 if (sigfig <= 1 && jlog==0) 1967 else if (sigfig <= 1.4 && jlog==1) 1968 else if (sigfig <= 3 && jlog ==1) 1969 else siground 1970 break; 1971 default : 1972 1973 // Round mantissa up to 1, 2, 2.5, 5, 1974 if (sigfig <= 1) siground 1975 else if (sigfig <= 2) siground 1976 else if (sigfig <= 5 && (!OptionTi 1977 else if (sigfig <= 6 && OptionTime 1978 else {siground 1979 break; 1980 } 1981 1982 BinWidth = siground* ::pow(10.,jlog); 1983 if (OptionTime) BinWidth *= timemulti; 1984 1985 // Get new bounds from new width BinWi 1986 1987 L90: 1988 alb = AL/BinWidth; 1989 if (TMath_Abs(alb) > 1e9) { 1990 BinLow = AL; 1991 BinHigh = AH; 1992 if (nbins > 10*nold && nbins > 10000) 1993 return; 1994 } 1995 lwid = int(alb); 1996 if (alb < 0) lwid--; 1997 BinLow = BinWidth*double(lwid); 1998 alb = AH/BinWidth + 1.00001; 1999 kwid = int(alb); 2000 if (alb < 0) kwid--; 2001 BinHigh = BinWidth*double(kwid); 2002 nbins = kwid - lwid; 2003 if (nold == -1) goto LOK; 2004 if (nold <= 5) { // Request 2005 if (nold > 1 || nbins == 1)goto LOK; 2006 BinWidth = BinWidth*2; 2007 nbins = 1; 2008 goto LOK; 2009 } 2010 if (2*nbins == nold && !OptionTime) {nte 2011 2012 LOK: 2013 double oldBinLow = BinLow; 2014 double oldBinHigh = BinHigh; 2015 int oldnbins = nbins; 2016 2017 double atest = BinWidth*0.0001; 2018 //if (TMath_Abs(BinLow-A1) >= atest) { 2019 //if (TMath_Abs(BinHigh-A2) >= atest) { 2020 if (AL-BinLow >= atest) { BinLow += Bi 2021 if (BinHigh-AH >= atest) { BinHigh -= Bi 2022 if (!OptionTime && BinLow >= BinHigh) { 2023 //this case may happen when nbins <=5 2024 BinLow = oldBinLow; 2025 BinHigh = oldBinHigh; 2026 nbins = oldnbins; 2027 } 2028 else if (OptionTime && BinLow>=BinHigh) 2029 nbins = 2*oldnbins; 2030 BinHigh = oldBinHigh; 2031 BinLow = oldBinLow; 2032 BinWidth = (oldBinHigh - oldBinLow)/n 2033 atest = BinWidth*0.0001; 2034 if (AL-BinLow >= atest) { BinLow += 2035 if (BinHigh-AH >= atest) { BinHigh -= 2036 } 2037 } 2038 2039 static void adjustBinSize( 2040 double A1,double A2,int nold 2041 ,double &BinLow, double &BinHigh, int &nbin 2042 ){ 2043 // Axis labels optimisation 2044 // ======================== 2045 // 2046 // This routine adjusts the bining of the 2047 // in order to have integer values for th 2048 // 2049 // _Input parameters: 2050 // 2051 // A1,A2 : Old WMIN,WMAX . 2052 // BinLow,BinHigh : New WMIN,WMAX . 2053 // nold : Old NDIV (primary divisions) 2054 // nbins : New NDIV . 2055 // 2056 BinWidth = TMath_Abs(A2-A1)/double(nold) 2057 if (BinWidth <= 1) { BinWidth = 1; BinLo 2058 else { 2059 int width = int(BinWidth/5) + 1; 2060 BinWidth = 5*width; 2061 BinLow = int(A1/BinWidth)*BinWidth 2062 2063 // We determine BinLow to have one tick 2064 // if there are negative labels. 2065 2066 if (A1 < 0) { 2067 for (int ic=0; ic<1000; ic++) { 2068 double rbl = BinLow/BinWidth; 2069 int ibl = int(BinLow/BinWidth 2070 if ( (rbl-ibl) == 0 || ic > wid 2071 } 2072 } 2073 } 2074 BinHigh = int(A2); 2075 nbins = 0; 2076 double XB = BinLow; 2077 while (XB <= BinHigh) { 2078 XB += BinWidth; 2079 nbins++; 2080 } 2081 BinHigh = XB - BinWidth; 2082 } 2083 void setLabelOffset(float aValue) { fLabelO 2084 void setLabelSize(float aValue) { fLabelSiz 2085 void setTitleOffset(float aValue) { fTitleO 2086 void setTitleSize(float aValue) { fTitleSiz 2087 public: 2088 void set_tick_size(float aValue) { fTickSiz 2089 2090 private: 2091 std::ostream& m_out; 2092 //int fMaxDigits; //!Number of digits above 2093 private: 2094 //TObject : 2095 unsigned int fBits; //bit field statu 2096 float fTickSize; //Size of pr 2097 float fLabelOffset; //Offset of 2098 float fLabelSize; //Size of la 2099 float fTitleOffset; //Offset of 2100 float fTitleSize; //Size of ti 2101 int fLabelFont; //Font for l 2102 std::string fTitle; //axis ti 2103 std::string fTimeFormat; //Time fo 2104 }; 2105 2106 }} 2107 2108 #endif