00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef DATA_H
00019 #define DATA_H
00020
00021 #ifndef TJUTILS_CONFIG_H
00022 #define TJUTILS_CONFIG_H
00023 #include <tjutils/config.h>
00024 #endif
00025
00026 #include <tjutils/tjfeedback.h>
00027
00028 #ifdef ODIN_DEBUG
00029 #define BZ_DEBUG
00030 #endif
00031
00032
00033
00034
00035 #include <blitz/blitz.h>
00036
00037
00038 #ifdef BZ_MUTEX_DECLARE
00039 #undef BZ_MUTEX_DECLARE
00040 #endif
00041 #ifdef BZ_MUTEX_INIT
00042 #undef BZ_MUTEX_INIT
00043 #endif
00044 #ifdef BZ_MUTEX_LOCK
00045 #undef BZ_MUTEX_LOCK
00046 #endif
00047 #ifdef BZ_MUTEX_UNLOCK
00048 #undef BZ_MUTEX_UNLOCK
00049 #endif
00050 #ifdef BZ_MUTEX_DESTROY
00051 #undef BZ_MUTEX_DESTROY
00052 #endif
00053
00054
00055
00056 #define BZ_MUTEX_DECLARE(name)
00057 #define BZ_MUTEX_INIT(name)
00058 #define BZ_MUTEX_LOCK(name)
00059 #define BZ_MUTEX_UNLOCK(name)
00060 #define BZ_MUTEX_DESTROY(name)
00061
00062
00063
00064 #include <blitz/array.h>
00065 #include <blitz/tinyvec-et.h>
00066 using namespace blitz;
00067
00068
00069 #include <tjutils/tjtypes.h>
00070 #include <tjutils/tjprofiler.h>
00071
00072 #include <odinpara/protocol.h>
00073
00074 #include <odindata/converter.h>
00075 #include <odindata/fileio_opts.h>
00076
00077
00078
00079 BZ_DECLARE_FUNCTION_RET (float2real, STD_complex);
00080 BZ_DECLARE_FUNCTION_RET (float2imag, STD_complex);
00081 BZ_DECLARE_FUNCTION_RET (creal, float)
00082 BZ_DECLARE_FUNCTION_RET (cimag, float)
00083 BZ_DECLARE_FUNCTION_RET (cabs, float)
00084 BZ_DECLARE_FUNCTION_RET (phase, float)
00085 BZ_DECLARE_FUNCTION (logc)
00086 BZ_DECLARE_FUNCTION (expc)
00087 BZ_DECLARE_FUNCTION (conjc)
00088
00089
00090 BZ_DECLARE_FUNCTION2(secureDivision)
00091 BZ_DECLARE_FUNCTION (secureInv)
00092
00093
00094 #ifdef STL_REPLACEMENT
00095 BZ_DECLARE_ARRAY_ET_SCALAR_OPS(tjstd_complex)
00096 #endif
00097
00098
00104
00105
00106 struct FileMapHandle {
00107 FileMapHandle() : fd(-1), offset(0), refcount(1) {}
00108 int fd;
00109 LONGEST_INT offset;
00110 int refcount;
00111 Mutex mutex;
00112 };
00113
00115
00126 template <typename T, int N_rank>
00127 class Data : public Array<T,N_rank> {
00128
00129 public:
00130
00131
00135 Data(const TinyVector<int,N_rank>& dimvec, const T& val=0) : Array<T,N_rank>(dimvec), fmap(0) {(*this)=val;}
00136
00137
00138
00139 Data() : fmap(0) {}
00140 Data(int extent1) : Array<T,N_rank>(extent1), fmap(0) {}
00141 Data(int extent1, int extent2) : Array<T,N_rank>(extent1,extent2), fmap(0) {}
00142 Data(int extent1, int extent2,int extent3) : Array<T,N_rank>(extent1,extent2,extent3), fmap(0) {}
00143 Data(int extent1, int extent2,int extent3,int extent4) : Array<T,N_rank>(extent1,extent2,extent3,extent4), fmap(0) {}
00144 Data(int extent1, int extent2,int extent3,int extent4,int extent5) : Array<T,N_rank>(extent1,extent2,extent3,extent4,extent5), fmap(0) {}
00145 Data(int extent1, int extent2,int extent3,int extent4,int extent5,int extent6) : Array<T,N_rank>(extent1,extent2,extent3,extent4,extent5,extent6), fmap(0) {}
00146 Data(int extent1, int extent2,int extent3,int extent4,int extent5,int extent6,int extent7) : Array<T,N_rank>(extent1,extent2,extent3,extent4,extent5,extent6,extent7), fmap(0) {}
00147 Data(int extent1, int extent2,int extent3,int extent4,int extent5,int extent6,int extent7,int extent8) : Array<T,N_rank>(extent1,extent2,extent3,extent4,extent5,extent6,extent7,extent8), fmap(0) {}
00148 Data(int extent1, int extent2,int extent3,int extent4,int extent5,int extent6,int extent7,int extent8,int extent9) : Array<T,N_rank>(extent1,extent2,extent3,extent4,extent5,extent6,extent7,extent8,extent9), fmap(0) {}
00149
00150
00159 Data(const STD_string& filename, bool readonly, const TinyVector<int,N_rank>& shape, LONGEST_INT offset=0 );
00160
00164 Data(const Data<T,N_rank>& d) : fmap(0) {Data<T,N_rank>::reference(d);}
00165
00169 Data(const Array<T,N_rank>& a) : Array<T,N_rank>(a), fmap(0) {}
00170
00174 Data(const tjarray<tjvector<T>,T>& a) : fmap(0) { (*this)=a;}
00175
00179 template<class T_expr>
00180 Data(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr) : Array<T,N_rank>(expr), fmap(0) {}
00181
00182
00186 ~Data();
00187
00188
00192 Data<T,N_rank>& operator = (const Data<T,N_rank>& d) {Array<T,N_rank>::operator=(d); return *this;}
00193
00197 Data<T,N_rank>& operator = (const Array<T,N_rank>& a) {Array<T,N_rank>::operator=(a); return *this;}
00198
00202 Data<T,N_rank>& operator = (const T& val) {Array<T,N_rank>::operator=(val); return *this;}
00203
00207 template<class T_expr>
00208 inline Data<T,N_rank>& operator = (BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr) {
00209 typedef _bz_typename T_expr::T_numtype T_numtype;
00210 evaluate(expr, _bz_update<T_numtype, _bz_typename T_expr::T_numtype>());
00211 return *this;
00212 }
00213
00217 Data<T,N_rank>& operator = (const tjarray<tjvector<T>,T>& a);
00218
00219
00220
00221 Array<T,N_rank> operator + (const Data<T,N_rank>& b) const {return Array<T,N_rank>(Array<T,N_rank>(*this)+Array<T,N_rank>(b));}
00222 Array<T,N_rank> operator - (const Data<T,N_rank>& b) const {return Array<T,N_rank>(Array<T,N_rank>(*this)-Array<T,N_rank>(b));}
00223 Array<T,N_rank> operator * (const Data<T,N_rank>& b) const {return Array<T,N_rank>(Array<T,N_rank>(*this)*Array<T,N_rank>(b));}
00224 Array<T,N_rank> operator / (const Data<T,N_rank>& b) const {return Array<T,N_rank>(Array<T,N_rank>(*this)/Array<T,N_rank>(b));}
00225
00226
00227
00228 Array<T,N_rank> operator + (const T& v) const {return Array<T,N_rank>(Array<T,N_rank>(*this)+v);}
00229 Array<T,N_rank> operator - (const T& v) const {return Array<T,N_rank>(Array<T,N_rank>(*this)-v);}
00230 Array<T,N_rank> operator * (const T& v) const {return Array<T,N_rank>(Array<T,N_rank>(*this)*v);}
00231 Array<T,N_rank> operator / (const T& v) const {return Array<T,N_rank>(Array<T,N_rank>(*this)/v);}
00232
00233
00234
00241 int read(const STD_string& format,const STD_string& filename, LONGEST_INT offset=0);
00242
00243
00249 template<typename T2>
00250 int read(const STD_string& filename, LONGEST_INT offset=0);
00251
00252
00258 int write(const STD_string& format,const STD_string& filename, autoscaleOption scaleopt=autoscale) const;
00259
00260
00265 template<typename T2>
00266 int write(const STD_string& filename, autoscaleOption scaleopt=autoscale) const;
00267
00268
00269
00275 int write(const STD_string& filename, fopenMode mode=overwriteMode) const;
00276
00286 int write_asc_file(const STD_string& filename, const Array<T,N_rank>& pre=defaultArray, const Array<T,N_rank>& post=defaultArray) const;
00287
00292 int read_asc_file(const STD_string& filename);
00293
00294
00300 int autowrite(const STD_string& filename, const FileWriteOpts& opts=FileWriteOpts(), const Protocol* prot=0) const;
00301
00307 int autoread(const STD_string& filename, const FileReadOpts& opts=FileReadOpts(), Protocol* prot=0);
00308
00312 bool is_filemapped() const {return fmap;}
00313
00317 operator tjarray<tjvector<T>,T> () const;
00318
00319
00324 TinyVector<int, N_rank> create_index(unsigned long index) const;
00325
00329 unsigned long create_linear_index(const TinyVector<int, N_rank>& indexvec) const;
00330
00336 void shift(unsigned int shift_dim, int shift);
00337
00347 void congrid(const TinyVector<int,N_rank>& newshape, const TinyVector<float,N_rank>* subpixel_shift=0, bool left_to_right=false);
00348
00349
00356 template<typename T2, int N_rank2> Data<T2,N_rank2>& convert_to(Data<T2,N_rank2>& dst, autoscaleOption scaleopt=autoscale) const;
00357
00358
00359 Data<T,N_rank>& convert_to(Data<T,N_rank>& dst, autoscaleOption scaleopt=autoscale) const;
00360
00361
00365 T* c_array();
00366
00367
00368
00369 void reference(const Data<T,N_rank>& d);
00370
00371
00372
00373 static Array<T,N_rank> defaultArray;
00374
00375
00376 private:
00377
00378 void interpolate1dim(unsigned int dim, int newsize, float subpixel_shift);
00379
00380 void detach_fmap();
00381
00382 FileMapHandle* fmap;
00383
00384 };
00385
00386 template <typename T, int N_rank>
00387 Array<T,N_rank> Data<T,N_rank>::defaultArray;
00388
00389
00393
00394
00395 #ifdef STREAM_REPLACEMENT
00396
00397 template<typename T, int N_rank>
00398 inline STD_ostream& operator << (STD_ostream& s,const Array<T,N_rank>&) {return s;}
00399
00400 template<typename T, int N_rank>
00401 inline STD_ostream& operator << (STD_ostream& s,const TinyVector<T,N_rank>&) { return s;}
00402
00403 inline STD_ostream& operator << (STD_ostream& s,const Range&) { return s;}
00404
00405 #endif
00406
00408
00409
00410
00411
00412
00413 template<int N_rank>
00414 TinyVector<int,N_rank> index2extent(const TinyVector<int,N_rank>& shape, unsigned int index) {
00415 TinyVector<int,N_rank> result;
00416 unsigned int temp=index;
00417 for(int i=N_rank-1;i>=0;i--){
00418 result(i)=temp%shape(i);
00419 temp=temp/shape(i);
00420 }
00421 return result;
00422 }
00423
00424
00426
00427
00428
00429
00430 template<typename T, int N_rank, typename T2>
00431 void convert_from_ptr(Data<T,N_rank>& dst, const T2* src, const TinyVector<int, N_rank>& shape, autoscaleOption scaleopt=autoscale) {
00432 Log<OdinData> odinlog("Data","convert_from_ptr");
00433
00434 int dstsize=product(shape);
00435 int srcsize=dstsize*Converter::get_elements((T)0)/Converter::get_elements((T2)0);
00436 ODINLOG(odinlog,normalDebug) << "dstsize/srcsize=" << dstsize << "/" << srcsize << STD_endl;
00437
00438 dst.resize(shape);
00439
00440 Converter::convert_array(src, dst.c_array(), srcsize, dstsize, scaleopt);
00441 }
00442
00443
00444 template<typename T, int N_rank>
00445 void convert_from_ptr(Data<T,N_rank>& dst, const T* src, const TinyVector<int, N_rank>& shape) {
00446 dst.reference(Array<T,N_rank>((T*)src, shape, duplicateData));
00447 }
00448
00449
00451
00452 template <typename T, int N_rank>
00453 Data<T,N_rank>::Data(const STD_string& filename, bool readonly, const TinyVector<int,N_rank>& shape, LONGEST_INT offset ) : fmap(new FileMapHandle) {
00454 T* ptr=(T*)filemap(filename, (LONGEST_INT)product(shape)*sizeof(T), offset, readonly, fmap->fd);
00455 if(ptr && (fmap->fd)>=0) {
00456 Array<T,N_rank>::reference(Array<T,N_rank>(ptr, shape, neverDeleteData));
00457 fmap->offset=offset;
00458 } else {
00459 delete fmap;
00460 fmap=0;
00461 }
00462 }
00463
00465
00466 template <typename T, int N_rank>
00467 void Data<T,N_rank>::detach_fmap() {
00468 Log<OdinData> odinlog("Data","detach_fmap");
00469 if(fmap) {
00470 fmap->mutex.lock();
00471 (fmap->refcount)--;
00472 ODINLOG(odinlog,normalDebug) << "fd/offset/refcount=" << fmap->fd << "/" << fmap->offset << "/" << fmap->refcount << STD_endl;
00473 if(!(fmap->refcount)) {
00474 fileunmap(fmap->fd, Array<T,N_rank>::data(), (LONGEST_INT)Array<T,N_rank>::size()*sizeof(T), fmap->offset);
00475 fmap->mutex.unlock();
00476 delete fmap;
00477 fmap=0;
00478 }
00479 if(fmap) fmap->mutex.unlock();
00480 }
00481 }
00482
00484
00485 template <typename T, int N_rank>
00486 Data<T,N_rank>::~Data() {
00487 detach_fmap();
00488 }
00489
00491
00492 template <typename T, int N_rank>
00493 void Data<T,N_rank>::reference(const Data<T,N_rank>& d) {
00494 Log<OdinData> odinlog("Data","reference");
00495 detach_fmap();
00496 fmap=d.fmap;
00497 if(fmap) {
00498 MutexLock lock(fmap->mutex);
00499 (fmap->refcount)++;
00500 ODINLOG(odinlog,normalDebug) << "fmap->refcount=" << fmap->refcount << STD_endl;
00501 }
00502 Array<T,N_rank>::reference(d);
00503 }
00504
00506
00507 template <typename T, int N_rank>
00508 Data<T,N_rank>& Data<T,N_rank>::operator = (const tjarray<tjvector<T>,T>& a) {
00509 Log<OdinData> odinlog("Data","=");
00510 if( a.dim() == N_rank ) {
00511 ndim nn=a.get_extent();
00512 TinyVector<int,N_rank> tv;
00513 for(unsigned int i=0;i<a.dim();i++) tv(i)=nn[i];
00514 resize(tv);
00515 for(unsigned int i=0;i<a.total();i++) (*this)(create_index(i))=a[i];
00516 } else ODINLOG(odinlog,errorLog) << "dimension mismatch: this=" << N_rank<< ", tjarray=" << a.dim() << STD_endl;
00517 return *this;
00518 }
00519
00520
00522
00523 template<typename T,int N_rank>
00524 int Data<T,N_rank>::read(const STD_string& format,const STD_string& filename, LONGEST_INT offset) {
00525 Log<OdinData> odinlog("Data","read");
00526 if(format==TypeTraits::type2label((u8bit)0)) return read<u8bit> (filename);
00527 if(format==TypeTraits::type2label((s8bit)0)) return read<s8bit> (filename);
00528 if(format==TypeTraits::type2label((u16bit)0)) return read<u16bit>(filename);
00529 if(format==TypeTraits::type2label((s16bit)0)) return read<s16bit>(filename);
00530 if(format==TypeTraits::type2label((u32bit)0)) return read<u32bit>(filename);
00531 if(format==TypeTraits::type2label((s32bit)0)) return read<s32bit>(filename);
00532 if(format==TypeTraits::type2label((float)0)) return read<float> (filename);
00533 if(format==TypeTraits::type2label((double)0)) return read<double>(filename);
00534 ODINLOG(odinlog,errorLog) << "Unable to read file " << filename << " with data type " << format << STD_endl;
00535 return -1;
00536 }
00537
00538
00540
00541 template<typename T,int N_rank>
00542 template<typename T2>
00543 int Data<T,N_rank>::read(const STD_string& filename, LONGEST_INT offset) {
00544 Log<OdinData> odinlog("Data","read");
00545 LONGEST_INT fsize=filesize(filename.c_str())-offset;
00546 LONGEST_INT nelements_file=fsize/sizeof(T2);
00547 LONGEST_INT length=product(Array<T,N_rank>::shape());
00548 ODINLOG(odinlog,normalDebug) << "fsize / nelements_file / length = " << fsize << " / " << nelements_file << " / " << length << STD_endl;
00549
00550 if(!length) return 0;
00551
00552 if(nelements_file<length) {
00553 ODINLOG(odinlog,errorLog) << "Size of file " << filename << " to small for reading" << STD_endl;
00554 return -1;
00555 }
00556
00557 STD_string srctype=TypeTraits::type2label((T2)0);
00558 STD_string dsttype=TypeTraits::type2label((T)0);
00559 ODINLOG(odinlog,normalDebug) << "srctype/dsttype=" << srctype << "/" << dsttype << STD_endl;
00560
00561 TinyVector<int,N_rank> fileshape(Array<T,N_rank>::shape());
00562 fileshape(N_rank-1) *= (Converter::get_elements((T)0)/Converter::get_elements((T2)0));
00563 Data<T2,N_rank> filedata(filename, true, fileshape, offset);
00564 filedata.convert_to(*this);
00565
00566 return 0;
00567 }
00568
00569
00571
00572 template<typename T,int N_rank>
00573 int Data<T,N_rank>::write(const STD_string& format, const STD_string& filename, autoscaleOption scaleopt) const {
00574 Log<OdinData> odinlog("Data","write");
00575 if(format==TypeTraits::type2label((u8bit)0)) return write<u8bit> (filename,scaleopt);
00576 if(format==TypeTraits::type2label((s8bit)0)) return write<s8bit> (filename,scaleopt);
00577 if(format==TypeTraits::type2label((u16bit)0)) return write<u16bit>(filename,scaleopt);
00578 if(format==TypeTraits::type2label((s16bit)0)) return write<s16bit>(filename,scaleopt);
00579 if(format==TypeTraits::type2label((u32bit)0)) return write<u32bit>(filename,scaleopt);
00580 if(format==TypeTraits::type2label((s32bit)0)) return write<s32bit>(filename,scaleopt);
00581 if(format==TypeTraits::type2label((float)0)) return write<float> (filename,scaleopt);
00582 if(format==TypeTraits::type2label((double)0)) return write<double>(filename,scaleopt);
00583 ODINLOG(odinlog,errorLog) << "Unable to write file " << filename << " with data type " << format << STD_endl;
00584 return -1;
00585 }
00586
00588
00589 template<typename T,int N_rank>
00590 int Data<T,N_rank>::write(const STD_string& filename, fopenMode mode) const {
00591 Log<OdinData> odinlog("Data","write");
00592 if(filename=="") return 0;
00593
00594 FILE* file_ptr=FOPEN(filename.c_str(),modestring(mode));
00595
00596 if(file_ptr==NULL) {
00597 ODINLOG(odinlog,errorLog) << "unable to create/open file >" << filename << "< - " << lasterr() << STD_endl;
00598 return -1;
00599 }
00600
00601 Data<T,N_rank> data_copy(*this);
00602
00603 LONGEST_INT nmemb=Array<T,N_rank>::numElements();
00604 LONGEST_INT count=fwrite(data_copy.c_array(),sizeof(T),nmemb,file_ptr);
00605 if(count!=nmemb) {
00606 ODINLOG(odinlog,errorLog) << "unable to fwrite to file >" << filename << "< - " << lasterr() << STD_endl;
00607 return -1;
00608 }
00609
00610 if(file_ptr!=NULL) fclose(file_ptr);
00611 return 0;
00612 }
00613
00615
00616 template<typename T,int N_rank>
00617 template<typename T2>
00618 int Data<T,N_rank>::write(const STD_string& filename, autoscaleOption scaleopt) const {
00619 Log<OdinData> odinlog("Data","write");
00620
00621 rmfile(filename.c_str());
00622
00623 ODINLOG(odinlog,normalDebug) << "mem(pre): " << Profiler::get_memory_usage() << STD_endl;
00624 Data<T2,N_rank> converted_data; convert_to(converted_data,scaleopt);
00625 ODINLOG(odinlog,normalDebug) << "mem(cnv): " << Profiler::get_memory_usage() << STD_endl;
00626 Data<T2,N_rank> filedata(filename,false,converted_data.shape());
00627 ODINLOG(odinlog,normalDebug) << "mem(map): " << Profiler::get_memory_usage() << STD_endl;
00628 filedata=converted_data;
00629
00630 return 0;
00631 }
00632
00633
00635
00636 template<typename T,int N_rank>
00637 int Data<T,N_rank>::write_asc_file(const STD_string& filename, const Array<T,N_rank>& pre, const Array<T,N_rank>& post) const {
00638 bool have_pre=false;
00639 bool have_post=false;
00640
00641 Data<T,N_rank> pre_data(pre);
00642 Data<T,N_rank> post_data(post);
00643 int n=Array<T,N_rank>::numElements();
00644
00645 if(pre_data.numElements()==n) have_pre=true;
00646 if(post_data.numElements()==n) have_post=true;
00647
00648 STD_ofstream ofs(filename.c_str());
00649 if(ofs.bad()) return -1;
00650
00651 T val;
00652
00653 for(int i=0; i<n; i++) {
00654 if(have_pre) {
00655 val=pre_data(pre_data.create_index(i));
00656 ofs << val << " ";
00657 }
00658 val=(*this)(create_index(i));
00659 ofs << val;
00660 if(have_post) {
00661 val=post_data(post_data.create_index(i));
00662 ofs << " " << val;
00663 }
00664 ofs << "\n";
00665 }
00666
00667 ofs.close();
00668 return 0;
00669 }
00670
00672
00673 template<typename T,int N_rank>
00674 int Data<T,N_rank>::read_asc_file(const STD_string& filename) {
00675 STD_ifstream ifs(filename.c_str());
00676 if(ifs.bad()) return -1;
00677
00678 STD_string valstr;
00679 for(int i=0; i<Array<T,N_rank>::numElements(); i++) {
00680 if(ifs.bad()) return -1;
00681 ifs >> valstr;
00682 TypeTraits::string2type(valstr,(*this)(create_index(i)));
00683 }
00684
00685 ifs.close();
00686 return 0;
00687 }
00688
00689
00691
00692
00693 int fileio_autowrite(const Data<float,4>& data, const STD_string& filename, const FileWriteOpts& opts, const Protocol* prot);
00694 int fileio_autoread(Data<float,4>& data, const STD_string& filename, const FileReadOpts& opts, Protocol* prot);
00695
00696
00697 template<typename T,int N_rank>
00698 int Data<T,N_rank>::autowrite(const STD_string& filename, const FileWriteOpts& opts, const Protocol* prot) const {
00699 Data<float,4> filedata; convert_to(filedata);
00700 return fileio_autowrite(filedata, filename, opts, prot);
00701 }
00702
00703 template<typename T,int N_rank>
00704 int Data<T,N_rank>::autoread(const STD_string& filename, const FileReadOpts& opts, Protocol* prot) {
00705 Data<float,4> filedata;
00706 int result=fileio_autoread(filedata, filename, opts, prot);
00707 if(result>0) filedata.convert_to(*this);
00708 return result;
00709 }
00710
00711
00713
00714 template<typename T,int N_rank>
00715 Data<T,N_rank>::operator tjarray<tjvector<T>,T> () const {
00716 tjarray<tjvector<T>,T> a;
00717 ndim nn(N_rank);
00718 for(unsigned int i=0; i<N_rank; i++) nn[i]=Array<T,N_rank>::extent(i);
00719 a.redim(nn);
00720 for(unsigned int i=0;i<a.total();i++) a[i]=(*this)(create_index(i));
00721 return a;
00722 }
00723
00724
00725
00727
00728 template<typename T,int N_rank>
00729 template<typename T2, int N_rank2>
00730 Data<T2,N_rank2>& Data<T,N_rank>::convert_to(Data<T2,N_rank2>& dst, autoscaleOption scaleopt) const {
00731 Log<OdinData> odinlog("Data","convert_to");
00732
00733 TinyVector<int,N_rank2> newshape; newshape=1;
00734 for(int i=0; i<(N_rank-N_rank2+1); i++) {
00735 int srcindex=i;
00736 if(srcindex>=0 && srcindex<N_rank) newshape(0)*=Array<T,N_rank>::extent(srcindex);
00737 }
00738 for(int i=0; i<(N_rank2-1); i++) {
00739 int srcindex=N_rank-N_rank2+1+i;
00740 if(srcindex>=0 && srcindex<N_rank) newshape(1+i)=Array<T,N_rank>::extent(srcindex);
00741 }
00742
00743
00744 newshape(N_rank2-1)=newshape(N_rank2-1)*Converter::get_elements((T)0)/Converter::get_elements((T2)0);
00745
00746 dst.resize(newshape);
00747
00748 Data<T,N_rank> src_copy(*this);
00749
00750 Converter::convert_array(src_copy.c_array(), dst.c_array(), src_copy.numElements(), dst.numElements(), scaleopt);
00751
00752 return dst;
00753 }
00754
00755
00756
00757 template<typename T,int N_rank>
00758 Data<T,N_rank>& Data<T,N_rank>::convert_to(Data<T,N_rank>& dst, autoscaleOption scaleopt) const {
00759 Log<OdinData> odinlog("Data","convert_to");
00760 if(scaleopt==noscale || !std::numeric_limits<T>::is_integer) {
00761 ODINLOG(odinlog,normalDebug) << "Using reference" << STD_endl;
00762 dst.reference(*this);
00763 } else {
00764 Data<T,N_rank> src_copy(*this);
00765 dst.resize(src_copy.shape());
00766 Converter::convert_array(src_copy.c_array(), dst.c_array(), src_copy.numElements(), dst.numElements(), scaleopt);
00767 }
00768 return dst;
00769 }
00770
00772
00773 template<typename T,int N_rank>
00774 TinyVector<int, N_rank> Data<T,N_rank>::create_index(unsigned long index) const {
00775 return index2extent<N_rank>(Array<T,N_rank>::shape(), index);
00776 }
00777
00779
00780 template<typename T,int N_rank>
00781 unsigned long Data<T,N_rank>::create_linear_index(const TinyVector<int, N_rank>& indexvec) const {
00782 unsigned long totalIndex=0,subsize;
00783 TinyVector<int, N_rank> nn(Array<T,N_rank>::extent());
00784 for(unsigned long i=0;i<N_rank;i++) {
00785 nn(i)=1;
00786 subsize=product(nn);
00787 if(!subsize) subsize=1;
00788 totalIndex+=subsize*indexvec(i);
00789 }
00790 return totalIndex;
00791 }
00792
00794
00795 template<typename T,int N_rank>
00796 void Data<T,N_rank>::shift(unsigned int shift_dim, int shift) {
00797 Log<OdinData> odinlog("Data","shift");
00798
00799 if(!shift) return;
00800
00801 if( shift_dim >= N_rank ){
00802 ODINLOG(odinlog,errorLog) << "shift dimension(" << shift_dim << ") >= rank of data (" << N_rank << ") !\n";
00803 return;
00804 }
00805
00806 int shift_extent=Array<T,N_rank>::extent(shift_dim);
00807 int abs_shift=abs(shift);
00808 if(shift_extent < abs_shift){
00809 ODINLOG(odinlog,errorLog) << "extent(" << shift_extent << ") less than shift(" << abs_shift << ") !\n";
00810 return;
00811 }
00812
00813 Data<T,N_rank> data_copy(Array<T,N_rank>::copy());
00814
00815 TinyVector<int,N_rank> index;
00816 for(int i=0; i<Array<T,N_rank>::numElements(); i++) {
00817 index=create_index(i);
00818 T val=data_copy(index);
00819 int shiftindex=index(shift_dim)+shift;
00820 if(shiftindex>=shift_extent) shiftindex-=shift_extent;
00821 if(shiftindex<0) shiftindex+=shift_extent;
00822 index(shift_dim)=shiftindex;
00823 (*this)(index)=val;
00824 }
00825
00826 }
00827
00828
00829
00831
00832 template<typename T,int N_rank>
00833 void Data<T,N_rank>::congrid(const TinyVector<int,N_rank>& newshape, const TinyVector<float,N_rank>* subpixel_shift, bool left_to_right) {
00834 Log<OdinData> odinlog("Data","congrid");
00835 for(int i=0;i<N_rank;i++) {
00836 ODINLOG(odinlog,normalDebug) << "oldshape/newshape(" << i << ")=" << Array<T,N_rank>::shape()(i) << "/" << newshape(i) << STD_endl;
00837 if(subpixel_shift) ODINLOG(odinlog,normalDebug) << "subpixel_shift(" << i << ")=" << (*subpixel_shift)(i) << STD_endl;
00838 }
00839
00840 for(int irank=0; irank<N_rank; irank++) {
00841 int dim=irank;
00842 if(!left_to_right) dim=N_rank-1-irank;
00843 float shift=0.0;
00844 if(subpixel_shift) shift=(*subpixel_shift)(dim);
00845 interpolate1dim(dim,newshape(dim),shift);
00846 }
00847 }
00848
00850
00851
00852 template<typename T,int N_rank>
00853 void Data<T,N_rank>::interpolate1dim(unsigned int dim, int newsize, float subpixel_shift) {
00854 Log<OdinData> odinlog("Data","interpolate1dim");
00855 ODINLOG(odinlog,normalDebug) << "dim/newsize=" << dim << "/" << newsize << STD_endl;
00856
00857 if(newsize==Array<T,N_rank>::shape()(dim) && subpixel_shift==0.0) {
00858 ODINLOG(odinlog,normalDebug) << "interpolation not required" << STD_endl;
00859 return;
00860 }
00861
00862 if(dim>=N_rank) {
00863 ODINLOG(odinlog,errorLog) << "dim is larger than N_rank" << STD_endl;
00864 return;
00865 }
00866 if(newsize<0) {
00867 ODINLOG(odinlog,errorLog) << "newsize is negative" << STD_endl;
00868 return;
00869 }
00870
00871 Array<T,N_rank> olddata(*this);
00872 olddata.makeUnique();
00873
00874 TinyVector<int,N_rank> oldshape(olddata.shape());
00875 int oldsize=oldshape(dim);
00876
00877 TinyVector<int,N_rank> newshape(oldshape);
00878 newshape(dim)=newsize;
00879 resize(newshape);
00880
00881
00882 TinyVector<int,N_rank> ortho_shape(oldshape);
00883 ortho_shape(dim)=1;
00884
00885
00886 unsigned long n_ortho=product(ortho_shape);
00887
00888 ODINLOG(odinlog,normalDebug) << "n_ortho=" << n_ortho << STD_endl;
00889
00890 TinyVector<int,N_rank> indexvec;
00891 T* oldoneline=new T[oldsize];
00892
00893 for(unsigned long iortho=0; iortho<n_ortho; iortho++) {
00894
00895 indexvec=index2extent<N_rank>(ortho_shape,iortho);
00896
00897 for(int j=0; j<oldsize; j++) {
00898 indexvec(dim)=j;
00899 oldoneline[j]=olddata(indexvec);
00900 }
00901
00902 T* newoneline=interpolate1D(oldoneline,oldsize,newsize,subpixel_shift);
00903
00904 for(int j=0; j<newsize; j++) {
00905 indexvec(dim)=j;
00906 (*this)(indexvec)=newoneline[j];
00907 }
00908
00909 delete[] newoneline;
00910 }
00911
00912 delete[] oldoneline;
00913 }
00914
00915
00917
00918 template<typename T,int N_rank>
00919 T* Data<T,N_rank>::c_array() {
00920 Log<OdinData> odinlog("Data","c_array");
00921
00922 bool need_copying=false;
00923
00924
00925 TinyVector<int,N_rank>ord=Array<T,N_rank>::ordering();
00926 for(int i=0; i<N_rank-1; i++) {
00927 if(ord(i)<ord(i+1)) need_copying=true;
00928 }
00929
00930
00931 for(int i=0; i<N_rank; i++) {
00932 if(!Array<T,N_rank>::isRankStoredAscending(i)) need_copying=true;
00933 }
00934
00935
00936 if(!Array<T,N_rank>::isStorageContiguous()) need_copying=true;
00937
00938 if(need_copying) {
00939 ODINLOG(odinlog,normalDebug) << "need_copying" << STD_endl;
00940 Data<T,N_rank> tmp(Array<T,N_rank>::shape());
00941 tmp=(*this);
00942 reference(tmp);
00943 }
00944
00945 return Array<T,N_rank>::data();
00946 }
00947
00948 #endif