| Bsoft 2.0.5 Bernard's software package

utilities.cpp
Go to the documentation of this file.
1
9 #include <errno.h>
10 #include <sys/sysctl.h>
11 #include <stdio.h>
12 #include "utilities.h"
13
14 #include <iostream>
15
16 #define MAX_GET_LEN 32
17
18 // Definition of global variables
19 int verbose(0); // Default: No output to the screen
20
21 ostream &tab(ostream &out)
22 {
23 return out << '\t';
24 }
25
36 string get_cmd_line(int argc, char **argv)
37 {
38 int i;
39 string cmd_line;
40
41 for ( i=0; i<argc; i++ )
42 cmd_line = cmd_line + argv[i] + " ";
43
44 if ( verbose & VERB_DEBUG )
45 cout << cmd_line << endl;
46
47 return cmd_line;
48 }
49
60 Bstring command_line_time(int n, char** strings)
61 {
62 time_t ti = time(NULL);
63
64 int i;
65 Bstring clstring("# ");
66
67 for ( i=0; i<n; i++ )
68 clstring = clstring + strings[i] + " ";
69
70 clstring = clstring + "\n# " + asctime(localtime(&ti)) + "\n";
71
72 if ( verbose & VERB_DEBUG )
73 cout << "DEBUG command_line_string: " << clstring << endl;
74
75 return clstring;
76 }
77
85 string get_user_name()
86 {
87 int bufsize;
88
89 if ( (bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) == -1 )
90 bufsize = 16384;
91
92 char buffer[bufsize];
93 passwd pw, *result = NULL;
94
95 string user_name("unknown");
96
97 if ( getpwuid_r(getuid(), &pw, buffer, bufsize, &result) == 0 && result)
98 user_name = pw.pw_name;
99
100 return user_name;
101 }
102
119 void usage(const char** use, int all)
120 {
121 int i;
122
123 if ( all )
124 for ( i = 0; use[i] != NULL; i++ )
125 cout << use[i] << endl;
126 else
127 for ( i = 0; use[i] && strstr(use[i], "Example") == 0; i++ )
128 cout << use[i] << endl;
129
130 cout << endl << "Bsoft version " << BVERSION << " (" << 8*sizeof(long) << " bit)" << endl << endl;
131
132 bexit(0);
133 }
134
144 SysType systype(int show)
145 {
146 SysType type = Unknown_System;
147 char* test = new char[8];
148 int* itest = (int *) test;
149 float* ftest = (float *) test;
150
151 memcpy(test, "jbh ", 8);
152
153 if ( itest[0] == 1784834080 && fabs(ftest[0] - 6.84272e+25) < 1e+21 )
154 type = BigIEEE;
155
156 if ( itest[0] == 543711850 && fabs(ftest[0] - 1.96837e-19) < 1e-23 )
157 type = LittleIEEE;
158
159 if ( ( ( verbose > VERB_PROCESS ) && show ) || ( verbose & VERB_DEBUG ) ) {
160 switch ( type ) {
161 case BigIEEE:
162 cout << "System type: Big-endian IEEE";
163 break;
164 case LittleIEEE:
165 cout << "System type: Little-endian IEEE";
166 break;
167 default:
168 cout << "System type: Unknown";
169 break;
170 }
171 cout << " (" << 8*sizeof(long) << ")" << endl << endl;
172 }
173
174 if ( verbose & VERB_DEBUG )
175 cout << "DEBUG systype: " << test << " " << itest[0] << " " << ftest[0] << " " << type << endl;
176
177 delete[] test;
178
179 return type;
180 }
181
186 size_t system_processors()
187 {
188 size_t np(1);
189
190 #ifdef OMP_H
191 np = omp_get_num_procs();
192 #endif
193 #ifdef HAVE_GCD
194 np = sysconf( _SC_NPROCESSORS_ONLN );
195 #endif
196
197 return np;
198 }
199
204 long system_memory()
205 {
206 #if defined(CTL_HW) && (defined(HW_MEMSIZE) || defined(HW_PHYSMEM64))
207
208 int mib[2];
209 mib[0] = CTL_HW;
210 #if defined(HW_MEMSIZE)
211 mib[1] = HW_MEMSIZE; // OSX
212 #elif defined(HW_PHYSMEM64)
213 mib[1] = HW_PHYSMEM64; // NetBSD, OpenBSD
214 #endif
215 u_int namelen = sizeof(mib) / sizeof(mib[0]);
216 long size(0);
217 size_t len = sizeof(size);
218
219 if (sysctl(mib, namelen, &size, &len, NULL, 0) == 0)
220 return size;
221
222 #elif defined(_SC_PHYS_PAGES)
223
224 #if defined(_SC_PAGESIZE) // FreeBSD, Linux, OpenBSD, and Solaris
225 return (long)sysconf( _SC_PHYS_PAGES ) *
226 (long)sysconf( _SC_PAGESIZE );
227
228 #elif defined(_SC_PAGE_SIZE)
229 return (long)sysconf( _SC_PHYS_PAGES ) *
230 (long)sysconf( _SC_PAGE_SIZE );
231 #endif
232
233 #elif defined(_SC_AIX_REALMEM) // AIX
234 return (long)sysconf( _SC_AIX_REALMEM ) * (long)1024L;
235
236 #endif
237
238 perror("system_memory: sysctl error");
239
240 return 0;
241 }
242
248 int memory_check(long mem_required)
249 {
250 long mem_avail = system_memory();
251
252 if ( verbose ) {
253 cout << "Memory available: " << mem_avail << endl;
254 cout << "Memory required: " << mem_required << " ("
255 << setprecision(2) << mem_required*100.0/mem_avail << " %)" << endl << endl;
256 }
257
258 if ( mem_avail < mem_required ) {
259 cerr << "Error: Not enough memory!" << endl;
260 cerr << "Memory available: " << mem_avail << endl;
261 cerr << "Memory required: " << mem_required << endl << endl;
262 bexit(-1);
263 }
264
265 return 1;
266 }
267
273 int bexit(int value)
274 {
275 exit(value);
276 return value;
277 }
278
288 DataType getdatatype(char letter)
289 {
290 DataType type;
291
292 switch ( letter ) {
293 case '1': type = Bit; break;
294 case 'b': type = UCharacter; break;
295 case 'c': type = SCharacter; break;
296 case 'u': type = UShort; break;
297 case 's': type = Short; break;
298 case 'j': type = UInteger; break;
299 case 'i': type = Integer; break;
300 case 'k': type = ULong; break;
301 case 'l': type = Long; break;
302 case 'f': type = Float; break;
303 case 'd': type = Double; break;
304 case 'S': type = Short; break;
305 case 'I': type = Integer; break;
306 case 'F': type = Float; break;
307 case 'D': type = Double; break;
308 default: type = Unknown_Type; break;
309 }
310
311 return type;
312 }
313
314
328 int select_numbers(Bstring& string, int n, int* numsel)
329 {
330 if ( !numsel ) {
331 cerr << "Error in select_numbers: array not allocated!" << endl;
332 return -1;
333 }
334
335 int i, j, k, nlev(0);
336
337 if ( string.length() < 1 || string == "all" ) {
338 for ( i=0; i<n; i++ ) numsel[i] = 1;
339 return 1;
340 } else {
341 for ( i=0; i<n; i++ ) numsel[i] = 0;
342 }
343
344 if ( verbose & VERB_DEBUG )
345 cout << "DEBUG select_numbers: string=" << string << " n=" << n << endl;
346
347 Bstring* s, *s2, *sc;
348 Bstring* strcol = string.split(":");
349 Bstring* strarr = NULL;
350
351 for ( k=1, sc = strcol; sc; sc = sc->next, k++ ) {
352 strarr = sc->split(",");
353
354 for ( s = strarr; s; s = s->next ) {
355 s2 = s->split("-");
356 i = j = s2->integer();
357 if ( s2->next ) j = s2->next->integer();
358 for ( ; i <= j && i < n; i++ ) numsel[i] = k;
359 string_kill(s2);
360 }
361
362 string_kill(strarr);
363 }
364
365 string_kill(strcol);
366
367 for ( nlev=0, i=0; i<n; i++ ) if ( nlev < numsel[i] ) nlev = numsel[i];
368
369 if ( verbose & VERB_DEBUG ) {
370 cout << "DEBUG select_numbers: ";
371 for ( i=0; i<n; i++ ) cout << numsel[i];
372 cout << endl;
373 }
374
375 return nlev;
376 }
377
378 vector<int> select_numbers(Bstring& string, int n)
379 {
380 vector<int> numsel(n, 0);
381
382 int i, j, k;
383
384 if ( string.length() < 1 || string == "all" ) {
385 for ( i=0; i<n; i++ ) numsel[i] = 1;
386 return numsel;
387 }
388
389 if ( verbose & VERB_DEBUG )
390 cout << "DEBUG select_numbers: string=" << string << " n=" << n << endl;
391
392 Bstring* s, *s2, *sc;
393 Bstring* strcol = string.split(":");
394 Bstring* strarr = NULL;
395
396 for ( k=1, sc = strcol; sc; sc = sc->next, k++ ) {
397 strarr = sc->split(",");
398
399 for ( s = strarr; s; s = s->next ) {
400 s2 = s->split("-");
401 i = j = s2->integer();
402 if ( s2->next ) j = s2->next->integer();
403 for ( ; i <= j && i < n; i++ ) numsel[i] = k;
404 string_kill(s2);
405 }
406
407 string_kill(strarr);
408 }
409
410 string_kill(strcol);
411
412 if ( verbose & VERB_DEBUG ) {
413 cout << "DEBUG select_numbers: ";
414 for ( i=0; i<n; i++ ) cout << numsel[i];
415 cout << endl;
416 }
417
418 return numsel;
419 }
420
433 int findNextPowerOf(int startNumber, int powerOf)
434 {
435 int rVal = powerOf;
436
437 if (powerOf <= 0 ) {
438 rVal = 0;
439 } else if (powerOf == 1) {
440 rVal = startNumber;
441 } else {
442 while (rVal < startNumber) {
443 rVal *= powerOf;
444 }
445 }
446
447 return rVal;
448 }
449
459 int get_integer(char* ptr, int len)
460 {
461 if ( len > MAX_GET_LEN ) {
462 cerr << "Error in get_integer: scanning length too large!" << endl;
463 return 0;
464 }
465 char temp[MAX_GET_LEN];
466 int d(0);
467 strncpy(temp, ptr, len);
468 temp[len] = 0;
469 sscanf(temp, "%d", &d);
470 return d;
471 }
472
482 float get_float(char* ptr, int len)
483 {
484 if ( len > MAX_GET_LEN ) {
485 cerr << "Error in get_integer: scanning length too large!" << endl;
486 return 0;
487 }
488 char temp[MAX_GET_LEN];
489 float f(0);
490 strncpy(temp, ptr, len);
491 temp[len] = 0;
492 sscanf(temp, "%f", &f);
493 return f;
494 }
495
504 void swapbytes(unsigned char* v, size_t n)
505 {
506 unsigned char t;
507 size_t i;
508
509 for ( i=0, n--; i<n; i++, n-- ) {
510 t = v[i];
511 v[i] = v[n];
512 v[n] = t;
513 }
514 }
515
525 void swapbytes(size_t size, unsigned char* v, size_t n)
526 {
527 if ( n < 2 ) return;
528
529 if ( verbose & VERB_DEBUG )
530 cout << "DEBUG swapbytes: size=" << size << " n=" << n << endl;
531
532 size_t i;
533
534 for ( i=0; i<size; i+=n, v+=n ) swapbytes(v, n);
535 }
536
548 void vax2ieee(unsigned char* v, int sb)
549 {
550 unsigned char t[4];
551 int i, shift, expnt;
552
553 if ( sb ) {
554 t[0] = v[2]; // Swap byte order
555 t[1] = v[3];
556 t[2] = v[0];
557 t[3] = v[1];
558 } else {
559 t[0] = v[1]; // Swap for VAX format
560 t[1] = v[0];
561 t[2] = v[3];
562 t[3] = v[2];
563 }
564 for ( i=0; i<4; i++ ) v[i] = t[i];
565
566 expnt = (v[0] << 1) | (v[1] >> 7); // Get exponent
567 if ( expnt == 0 )
568 if ( v[0] == 0 ) // Special case zero
569 memset(t, '\0', 4);
570 else { // Special case infinity or NaN
571 t[0] = 0xff;
572 t[1] = v[1] | 0x80;
573 }
574 else if ( expnt > 2 ) // Normalized value
575 t[0] = v[0] - 0x01; // Subtract 2 from the exponent
576 else { // Denormalized value
577 shift = 3 - expnt;
578 t[0] = v[0] & 0x80; // Keep sign, expnt = 0
579 t[1] = ( (v[1] & 0x7f) >> shift ) | ( 0x10 << expnt );
580 t[2] = ( v[1] << ( 8-shift ) ) | ( v[2] >> shift );
581 t[3] = ( v[2] << ( 8-shift ) ) | ( v[3] >> shift );
582 }
583 for ( i=0; i<4; i++ ) v[i] = t[i];
584 }
585
594 double angle_set_negPI_to_PI(double angle)
595 {
596 if ( !isfinite(angle) ) return 0;
597
598 // angle = fmod(angle, TWOPI);
599 angle -= TWOPI*(long(angle/TWOPI));
600 while ( angle <= -M_PI ) angle += TWOPI;
601 while ( angle > M_PI ) angle -= TWOPI;
602
603 return angle;
604 }
605
622 float remove_negative_zeros(float value0, float threshold)
623 {
624 float value;
625
626 if ( (value0 > threshold) && (value0 < 0) )
627 value = 0;
628 else
629 value = value0;
630
631 return value;
632 }
633
645 size_t get_chunk_size(size_t datasize)
646 {
647 size_t np = system_processors();
648 size_t chunk_size = datasize/np;
649
650 if ( chunk_size < datasize && chunk_size < MIN_SIZE_FOR_THREADING ) {
651 chunk_size = MIN_SIZE_FOR_THREADING;
652 np = (datasize - 1)/chunk_size + 1;
653 }
654
655 if ( verbose & VERB_PROCESS )
656 cout << "Number of processors: " << np << endl << endl;
657
658 if ( verbose & VERB_FULL )
659 cout << "Chunk size: " << chunk_size << endl << endl;
660
661 if ( verbose & VERB_DEBUG )
662 cout << "DEBUG get_chunk_size: chunk_size = " << chunk_size << endl;
663
664 return chunk_size;
665 }
666
679 size_t get_chunk_size(size_t datasize, size_t c)
680 {
681 size_t np = system_processors();
682 size_t chunk_size(datasize/np);
683
684 while ( chunk_size%c ) chunk_size++;
685
686 if ( chunk_size < datasize && chunk_size < MIN_SIZE_FOR_THREADING ) {
687 chunk_size = MIN_SIZE_FOR_THREADING;
688 np = (datasize - 1)/chunk_size + 1;
689 }
690
691 if ( verbose & VERB_PROCESS )
692 cout << "Number of processors: " << np << endl << endl;
693
694 if ( verbose & VERB_FULL )
695 cout << "Chunk size: " << chunk_size << endl << endl;
696
697 if ( verbose & VERB_DEBUG )
698 cout << "DEBUG get_chunk_size: chunk_size = " << chunk_size << endl;
699
700 return chunk_size;
701 }
702
703
716 int error_show(const char* message, const char* file, int line)
717 {
718 char string[1024];
719
720 snprintf(string, 1024, "[%s:%d] %s", file, line, message);
721
722 perror(string);
723
724 if ( errno ) cerr << "errno " << errno << ": ";
725
726 switch ( errno ) {
727 case ENOENT:
728 cerr << "Make sure the file exists and the path to the file is correct" << endl;
729 break;
730 case EACCES:
731 cerr << "Make sure you have permission to write to this directory" << endl;
732 break;
733 case ENOMEM:
734 cerr << "The memory available on this computer may be insufficient" << endl;
735 break;
736 default:
737 cerr << endl;
738 }
739
740 return errno;
741 }
742
755 int error_show(string message, string file, int line)
756 {
757 // char string[1024];
758
759 // snprintf(string, 1024, "[%s:%d] %s", file, line, message);
760
761 string s = "[" + file + ":" + to_string(line) + "] " + message;
762
763 perror(s.c_str());
764 // cout << s << endl;
765
766 if ( errno ) cerr << "errno " << errno << ": ";
767
768 switch ( errno ) {
769 case ENOENT:
770 cerr << "Make sure the file exists and the path to the file is correct" << endl;
771 break;
772 case EACCES:
773 cerr << "Make sure you have permission to write to this directory" << endl;
774 break;
775 case ENOMEM:
776 cerr << "The memory available on this computer may be insufficient" << endl;
777 break;
778 default:
779 cerr << endl;
780 }
781
782 return errno;
783 }
784
systype
SysType systype(int show)
Finds the system type - mostly just for byte order.
Definition: utilities.cpp:144
DataType
DataType
Base data type specifier.
Definition: utilities.h:146
BVERSION
#define BVERSION
Definition: utilities.h:9
LittleIEEE
Definition: utilities.h:131
BigIEEE
Definition: utilities.h:129
utilities.h
Header file for general utilities.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
Integer
Definition: utilities.h:154
MIN_SIZE_FOR_THREADING
#define MIN_SIZE_FOR_THREADING
Definition: utilities.h:46
SCharacter
Definition: utilities.h:150
SysType
SysType
Definition: utilities.h:127
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
get_cmd_line
string get_cmd_line(int argc, char **argv)
Returns the command line as a string.
Definition: utilities.cpp:36
Long
Definition: utilities.h:156
error_show
int error_show(const char *message, const char *file, int line)
Displays the error with file and line reference.
Definition: utilities.cpp:716
get_integer
int get_integer(char *ptr, int len)
Converts a defined length string into an integer.
Definition: utilities.cpp:459
Float
Definition: utilities.h:157
UInteger
Definition: utilities.h:153
get_user_name
string get_user_name()
Returns the user name.
Definition: utilities.cpp:85
M_PI
#define M_PI
Definition: utilities.h:59
isfinite
bool isfinite(complex< T > &value)
memory_check
int memory_check(long mem_required)
Checking if there is enough memory, abort if not.
Definition: utilities.cpp:248
system_processors
size_t system_processors()
Returns the number of processors.
Definition: utilities.cpp:186
get_chunk_size
size_t get_chunk_size(size_t datasize)
Returns the chunk size per thread.
Definition: utilities.cpp:645
Double
Definition: utilities.h:158
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bstring::next
Bstring * next
Definition: Bstring.h:31
ULong
Definition: utilities.h:155
usage
void usage(const char **use, int all)
Prints usage information.
Definition: utilities.cpp:119
length
double length(vector< T > v)
Definition: Vector3.h:528
sb
int sb(0)
use
const char * use[]
Definition: b3v.cpp:19
MAX_GET_LEN
#define MAX_GET_LEN
Definition: utilities.cpp:16
angle_set_negPI_to_PI
double angle_set_negPI_to_PI(double angle)
Returns an angle between -PI and PI.
Definition: utilities.cpp:594
UCharacter
Definition: utilities.h:149
Bstring
Definition: Bstring.h:29
Bit
Definition: utilities.h:148
findNextPowerOf
int findNextPowerOf(int startNumber, int powerOf)
Finds the next greatest number that is a power of a given number.
Definition: utilities.cpp:433
select_numbers
int select_numbers(Bstring &string, int n, int *numsel)
Converts a string with a selection specification into an integer array.
Definition: utilities.cpp:328
vax2ieee
void vax2ieee(unsigned char *v, int sb)
Converts VAX floating point format to IEEE floating point format.
Definition: utilities.cpp:548
show
int show(0)
command_line_time
Bstring command_line_time(int n, char **strings)
Returns a set of strings and time in a string.
Definition: utilities.cpp:60
Bstring::integer
long integer()
Definition: Bstring.cpp:539
Short
Definition: utilities.h:152
remove_negative_zeros
float remove_negative_zeros(float value0, float threshold)
Prevent a negative sign from being placed in front of zero value in a text file.
Definition: utilities.cpp:622
Unknown_Type
Definition: utilities.h:147
getdatatype
DataType getdatatype(char letter)
Get the data type indicated by a single letter code.
Definition: utilities.cpp:288
system_memory
long system_memory()
Returns system memory size.
Definition: utilities.cpp:204
UShort
Definition: utilities.h:151
Unknown_System
Definition: utilities.h:128
verbose
int verbose(0)
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
get_float
float get_float(char *ptr, int len)
Converts a defined length string into a floating point number.
Definition: utilities.cpp:482
bexit
int bexit(int value)
Exit function for cleanup and debugging.
Definition: utilities.cpp:273
TWOPI
#define TWOPI
Definition: utilities.h:68
swapbytes
void swapbytes(unsigned char *v, size_t n)
Swaps bytes.
Definition: utilities.cpp:504
Bstring::split
Bstring * split()
Definition: Bstring.cpp:597
string_kill
int string_kill(Bstring *list)
Kills a string linked list.
Definition: Bstring.cpp:760