Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 3 4 #ifndef tools_data_axis 5 #define tools_data_axis 6 7 #include "mathf" 8 9 namespace tools { 10 11 class data_axis { 12 public: 13 data_axis():m_min_value(0),m_max_value(0),m_is_log(false){} 14 virtual ~data_axis(){} 15 public: 16 data_axis(const data_axis& a_from) 17 :m_min_value(a_from.m_min_value) 18 ,m_max_value(a_from.m_max_value) 19 ,m_is_log(a_from.m_is_log) 20 {} 21 data_axis& operator=(const data_axis& a_from){ 22 m_min_value = a_from.m_min_value; 23 m_max_value = a_from.m_max_value; 24 m_is_log = a_from.m_is_log; 25 return *this; 26 } 27 public: 28 bool set_is_log(bool a_v) {if(m_is_log==a_v) return false;m_is_log = a_v;return true;} 29 bool set_min_value(float a_v) {if(m_min_value==a_v) return false;m_min_value = a_v;return true;} 30 bool set_max_value(float a_v) {if(m_max_value==a_v) return false;m_max_value = a_v;return true;} 31 #ifdef tools_data_axis //g4tools backcomp : 32 bool is_log(bool a_v) {if(m_is_log==a_v) return false;m_is_log = a_v;return true;} 33 bool min_value(float a_v) {if(m_min_value==a_v) return false;m_min_value = a_v;return true;} 34 bool max_value(float a_v) {if(m_max_value==a_v) return false;m_max_value = a_v;return true;} 35 #endif 36 float min_value() const {return m_min_value;} 37 float max_value() const {return m_max_value;} 38 bool is_log() const {return m_is_log;} 39 40 void adjust() { //from hippodraw. 41 int _axis = 0; 42 float step; 43 float mylow, myhigh; 44 int N_NICE = 4; 45 static const float nice[/*N_NICE*/4] = { 1.0,2.0,2.5,5.0 }; 46 47 if (m_min_value > m_max_value) { 48 float low = m_min_value; 49 m_min_value = m_max_value; 50 m_max_value = low; 51 } else if (m_min_value == m_max_value) { 52 float value = m_min_value; 53 m_min_value = value - 1; 54 m_max_value = value + 1; 55 return; 56 } 57 58 //if (m_steps <= 0) { //if letting the if and m_steps as a field, twice this function do not give the same result. 59 _axis = 1; 60 unsigned int m_steps = 10; 61 //} 62 63 // Round the "bin width" to a nice number. 64 // If this is being done for an axis (ie m_steps was 0 , then 65 // we don't have to go > *m_max_value. 66 // 67 float w = (m_max_value - m_min_value)/((float)m_steps); 68 float mag = ffloor(flog10(w)); 69 int i = 0; 70 do { 71 step = nice[i] * fpow(10.0,mag); 72 mylow = ffloor(m_min_value/step) * step; 73 //myhigh = _axis==1 ? fceil(m_max_value/step) * step : mylow + step * m_steps; 74 myhigh = fceil(m_max_value/step) * step; //quiet Coverity. 75 i++; 76 if (i>=N_NICE) {i = 0;mag++;} 77 } 78 while ( ( (_axis==1) && (myhigh < m_max_value)) || 79 ( (_axis==0) && (myhigh <= m_max_value)) ); 80 81 float range = myhigh - mylow; 82 83 // we now have decided on a range. Try to move 84 // m_min_value/m_max_value a little 85 // to end up on a nice number. 86 // 87 // first check if either end is near 0.0 88 if ( !m_is_log && (m_min_value >= 0.0) && 89 (( (_axis==1) && (range>=m_max_value) ) || 90 ( (_axis==0) && (range>m_max_value) )) ) { 91 m_min_value = 0.0; 92 m_max_value = range; 93 return; 94 } 95 96 if ( (( (_axis==1) && (m_max_value<=0.0) ) || 97 ( (_axis==0) && (m_max_value<0.0) )) 98 && (-range<=m_min_value)) { 99 m_max_value = 0.0; 100 m_min_value = -range; 101 return; 102 } 103 104 // try to round *m_min_value. 105 // correction 106 if( m_is_log && (m_min_value<=0.0)) m_min_value = 1.0; 107 108 i = N_NICE-1; 109 mag = myhigh != 0.0 ? fceil(flog10(ffabs(myhigh))) : fceil(flog10(ffabs(mylow))); 110 111 do { 112 step = nice[i] * fpow(10.0,mag); 113 mylow = ffloor(m_min_value/step) * step; 114 myhigh = mylow + range; 115 i--; 116 if (i<0) { 117 i = N_NICE-1; 118 mag--; 119 } 120 } 121 while (( m_is_log && (mylow <= 0.0) ) || 122 ( (_axis==1) && (myhigh < m_max_value) ) || 123 ( (_axis==0) && (myhigh <= m_max_value) ) ); 124 125 m_min_value = mylow; 126 m_max_value = myhigh; 127 } 128 protected: 129 float m_min_value; 130 float m_max_value; 131 //int m_steps; 132 bool m_is_log; 133 }; 134 135 } 136 137 #endif