Loading...
Searching...
No Matches
ValueScaling.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31#ifndef IMAGE_SCALING2_H_
32#define IMAGE_SCALING2_H_ "ImageScaling 0.1, 2017/09 Markus.Peura@fmi.fi"
33
34#include <drain/TypeUtils.h>
35#include <drain/UniTuple.h>
36#include <stddef.h> // size_t
37
38#include "Range.h"
39
40//#include "Geometry.h"
41//#include "Coordinates.h"
42
43
44namespace drain
45{
46
47
48//extern drain::Log iLog;
49
50// If the intensities of the image correspond to a physical value (like temperature), this is the recommended way to copy.
51
53
63class ValueScaling : public UniTuple<double,2> { // UniTuple<double,4>{
64public:
65
67 double & scale;
68
70 double & offset;
71
74
75
76 inline
77 ValueScaling(double scale=1.0, double offset = 0.0) : // RANGE ok? double scaleOut=1.0, double offsetOut=0.0) :
78 scale(this->next()), offset(this->next()) //, physRange(this->tuple(), 2)
79 {
80 //setConversionScale(scale, offset, scaleOut, offsetOut);
82 physRange.set(0,0);
83 };
84
85 inline
86 ValueScaling(double scale, double offset, const drain::Range<double> & range) : //, double scaleOut=1.0, double offsetOut=0.0) :
87 scale(this->next()), offset(this->next()) //, physRange(this->tuple(), 2)
88 {
89 //setConversionScale(scale, offset, scaleOut, offsetOut);
91 physRange.set(range); // TODO tune: scaleOut, offsetOut
92 };
93
94 inline
95 ValueScaling(const drain::ValueScaling & scaling) :
96 scale(this->next()), offset(this->next()) //, physRange(this->tuple(), 2)
97 {
98 this->assignSequence(scaling);
99 physRange.set(scaling.physRange);
100 };
101
102 //
103 inline
104 ValueScaling(const drain::UniTuple<double,2> & scaling) :
105 scale(this->next()), offset(this->next())
106 {
107 setScaling(scaling[0], scaling[1]);
108 };
109
110
111 // Conversion scaling
112 inline
113 ValueScaling(const drain::ValueScaling & scalingIn, const drain::ValueScaling & scalingOut) :
114 scale(this->next()), offset(this->next())
115 {
116 setConversionScale(scalingIn, scalingOut);
117 // physRange??? intersection / union
118 };
119
120 virtual inline
121 ~ValueScaling(){};
122
123
124 inline
125 ValueScaling & operator=(const drain::ValueScaling & scaling){
126 if (&scaling != this){
127 this->assignSequence(scaling);
128 physRange.set(scaling.physRange);
129 }
130 return *this;
131 }
132
134 virtual inline
135 void setScaling(double scale, double offset){
136 this->set(scale, offset); // virtual IMPORTANT for channels/view
137 }
138
139 virtual
140 void setScaling(const ValueScaling & scaling){
141 this->assignSequence(scaling);
142 }
143
145 virtual inline // LATER: scalingPtr!
146 const ValueScaling & getScaling() const {
147 return *this;
148 }
149
151 virtual inline // LATER: scalingPtr!
153 return *this;
154 }
155
156
157
159 inline
161 set(1.0, 0.0);
162 }
163
165
171 inline
172 void setNormalScale(const std::type_info & t){
173 if (Type::call<drain::typeIsSmallInt>(t))
174 set(1.0/drain::Type::call<drain::typeMax,double>(t), 0.0);
175 else // warn? (esp. for int and long int)
176 set(1.0, 0.0); // absolute scale
177 }
178
180 inline
181 void setConversionScale(double scale, double offset = 0.0, double scaleOut=1.0, double offsetOut=0.0){
182 set(scale/scaleOut, (offset - offsetOut)/scaleOut);
183 }
184
186 inline
188 set(s2.scale/s1.scale, (s2.offset-s1.offset) / s1.scale);
189 }
190
191 //template <typename T>
192 inline
193 void setConversionScale(const Range<double> & r1, const Range<double> & r2){
194 set(r2.width()/r1.width(), r2.min - r2.width()/r1.width()*r1.min);
195 }
196
198 void setOptimalScale(const std::type_info & t);
199
200
202 inline
203 void setPhysicalScale(const std::type_info & t, double min, double max){
204 setPhysicalRange(min, max);
206 }
207
209
212 inline
213 void setPhysicalScale(const std::type_info & t, const drain::ValueScaling & scaling){
216 };
217
219 inline
220 const Range<double> & getPhysicalRange() const { // , const std::string &unit ?
221 return physRange;
222 }
223
225 inline
226 Range<double> & getPhysicalRange() { // , const std::string &unit ?
227 return physRange;
228 }
229
231 inline
232 void setPhysicalMax(double max){ // dangerous (after min?)
233 setPhysicalRange(0.0, max);
234 }
235
237 template <class T>
238 inline
239 void setPhysicalRange(const Range<T> &range){ // , const std::string &unit ?
241 }
242
244 inline
245 void setPhysicalRange(double min, double max){ // , const std::string &unit ?
246 physRange.set(min,max);
247 }
248
250 inline
251 double getScale() const { return scale; }
252
254 inline
255 double getOffset() const { return offset; }
256
258
261 inline
262 bool isScaled() const {
263 return (scale!=1.0) || (offset!=0.0);
264 }
265
267 inline
268 double getMinPhys() const {
269 return physRange.min;
270 }
271
273 inline
274 double getMaxPhys() const {
275 return physRange.max;
276 }
277
279 inline
280 bool isPhysical() const {
281 return (!physRange.empty());
282 }
283
285 /* short => float
286 *
287 */
288 //inline
289 void adoptScaling(const drain::ValueScaling & srcScaling, const std::type_info & srcType, const std::type_info & dstType = typeid(void));
290
291
293 inline
294 double fwd(double x) const {
295 return scale*x + offset;
296 }
297
299 inline
300 double inv(double y) const {
301 return (y - offset) / scale;
302 }
303
304 virtual inline
305 void toStream(std::ostream & ostr) const override {
306 ostr << scale << ',' << offset;
307 if (isPhysical())
308 ostr << " [" << physRange << ']';
309 }
310
311 inline
312 std::string str() const{
313 std::stringstream sstr;
314 toStream(sstr);
315 return sstr.str();
316 }
317
318
319
320};
321
322inline
323std::ostream & operator<<(std::ostream &ostr, const drain::ValueScaling & s){
324 s.toStream(ostr);
325 return ostr;
326}
327
328} // drain::
329
330#endif
331
332// Drain
Definition Range.h:52
tuplebase_t & assignSequence(T &sequence, bool LENIENT=false)
Proposed for tuples only; derived classes should not shadow this.
Definition TupleBase.h:287
Tuple of N elements of type T.
Definition UniTuple.h:65
Linear scaling and physical range for image intensities.
Definition ValueScaling.h:63
double & scale
Multiplicative coefficient \i a in: y = ax + b.
Definition ValueScaling.h:67
void setPhysicalRange(double min, double max)
Sets the supported range for physical values. Does not change scaling or type.
Definition ValueScaling.h:245
const Range< double > & getPhysicalRange() const
Returns a typical or supported range for physical values.
Definition ValueScaling.h:220
double getMinPhys() const
Returns the minimum physical value.
Definition ValueScaling.h:268
drain::Range< double > physRange
Minimum and maximum physical value of the imaged quantity (not limited to corresponding to minCodeVal...
Definition ValueScaling.h:73
virtual ValueScaling & getScaling()
Get linear scaling.
Definition ValueScaling.h:152
bool isPhysical() const
Returns true, physical intensity range has been set.
Definition ValueScaling.h:280
bool isScaled() const
Returns true, if scaling has effect ie. scale!=1.0 or offset!=0.0.
Definition ValueScaling.h:262
void setAbsoluteScale()
If the intensities of the image correspond to an absolute value (like count) then the scale should be...
Definition ValueScaling.h:160
double fwd(double x) const
Forward scaling: given encoded value x, returns corresponding value (possibly physically meaningful).
Definition ValueScaling.h:294
double & offset
Additive coefficient \i b in: y = ax + b.
Definition ValueScaling.h:70
void setPhysicalRange(const Range< T > &range)
Sets the supported range for physical values. Does not change scaling or type.
Definition ValueScaling.h:239
double getOffset() const
Returns the intensity scaling offset, ie. b in a*x + b . See set setScale()
Definition ValueScaling.h:255
Range< double > & getPhysicalRange()
Returns a typical or supported range for physical values. Modifying the range will not change scaling...
Definition ValueScaling.h:226
void setConversionScale(double scale, double offset=0.0, double scaleOut=1.0, double offsetOut=0.0)
If the intensities of the image correspond to a physical value (like temperature),...
Definition ValueScaling.h:181
void setPhysicalMax(double max)
In integer-valued images, set the physical values corresponding to [0, maxCodeValue].
Definition ValueScaling.h:232
double getMaxPhys() const
Returns the maximum physical value.
Definition ValueScaling.h:274
void setNormalScale(const std::type_info &t)
For "small integer" types, resets offset and scale such that maximum code value corresponds to 1....
Definition ValueScaling.h:172
void setConversionScale(const drain::ValueScaling &s1, const drain::ValueScaling &s2)
Set scaling for which scaling.inv(x) = s2.inv(s1.fwd(x))
Definition ValueScaling.h:187
void adoptScaling(const drain::ValueScaling &srcScaling, const std::type_info &srcType, const std::type_info &dstType=typeid(void))
Sets scale and offset according to physical range and current type.
Definition ValueScaling.cpp:73
virtual void setScaling(double scale, double offset)
Set linear scaling.
Definition ValueScaling.h:135
void setPhysicalScale(const std::type_info &t, const drain::ValueScaling &scaling)
Sets physical range (min, max) and scales storage type accordingly.
Definition ValueScaling.h:213
double inv(double y) const
Inverse scaling: given physically meaningful value y, returns the corresponding code value.
Definition ValueScaling.h:300
void setOptimalScale(const std::type_info &t)
If storage type is integer, adjust scale such that resolution is maximized.
Definition ValueScaling.cpp:36
void setPhysicalScale(const std::type_info &t, double min, double max)
Sets physical range (min, max) and scales storage type accordingly.
Definition ValueScaling.h:203
virtual const ValueScaling & getScaling() const
Get linear scaling.
Definition ValueScaling.h:146
double getScale() const
Returns the intensity scaling factor. See set setScale()
Definition ValueScaling.h:251
Definition DataSelector.cpp:1277