00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <ctype.h>
00023 #include <string.h>
00024 #include <stdlib.h>
00025 #include <time.h>
00026 #include <math.h>
00027 #include <unistd.h>
00028 #include <fcntl.h>
00029 #include <sys/types.h>
00030 #include <sys/stat.h>
00031
00032 #include "marcmd.h"
00033 #include "esd.h"
00034 #include "marglobals.h"
00035 #include "mararrays.h"
00036 #include "config.h"
00037 #include "version.h"
00038 #include <mar345_header.h>
00039 #include <mar300_header.h>
00040 #include <nb_header.h>
00041 #include "marxf.h"
00042
00043 #define NB_SIZE 1024
00044 #define BOXSIZE 100
00045 #define BOX_OFF 100
00046
00047 #define ltell(a) lseek( a, 0, SEEK_CUR )
00048 #define min0(a,b) if ( b < a ) a = b
00049 #define max0(a,b) if ( b > a ) a = b
00050
00051
00052
00053
00054 MAR345_HEADER h345;
00055 char large_mem = 1;
00056 char scan_in_progress = 0;
00057 char xf_in_progress = 0;
00058 char op_in_progress = 0;
00059 char last_image[128] = { ""} ;
00060 char is_data = 0;
00061
00062 int last_total = 0;
00063 int bytes2xfer;
00064
00065 static int n1=0,n2=0,adcavg1,adcavg2,adcavg11,adcavg21;
00066 static int xf_histo[65600];
00067 static int hist_begin, hist_end, hist_max;
00068 static int add_A, add_B;
00069 int valmax, valmin;
00070 int sp_pixels, xf_pixels;
00071 int maximum_pixels;
00072 int maximum_block;
00073 int maximum_bytes;
00074 int data_offset;
00075 int current_pixel;
00076 int xform_status;
00077
00078 int Imax;
00079 float AvgI,SigI;
00080
00081
00082
00083
00084 static char adc_channel = 0;
00085 static unsigned short i2_record[MAX_SIZE];
00086 static STRONG strong_rec[MAX_SIZE/2];
00087 static FILE *fpnb = NULL;
00088
00089 static int fdspiral = -1;
00090 static int iindex = 0;
00091 static int i_x0 = 0;
00092 static int j_y0 = 0;
00093 static int max_spiral_int = 0;
00094 static int spiral_offset = 0;
00095 static int ac_size = 0;
00096 static int i_rec = 1;
00097 static int xf_rec = 0;
00098 static int ns_rec = 0;
00099 static int fdxf = 0;
00100 static int swap_nb = 0;
00101 static char start_with_A = 1;
00102 static int spiral_size;
00103 static int total_pixels;
00104 static int last_block;
00105 static int last_pixel;
00106 static int istrong;
00107 static int nskip;
00108 static int poff;
00109 static int nb_index;
00110 static int lin_dxy[8];
00111 static int saturation;
00112 static char spiral_only;
00113 static float fract_intens;
00114
00115 static MAR300_HEADER h300;
00116 static MARNB_HEADER nb;
00117
00118 static signed char x_rec [NB_SIZE];
00119 static signed char y_rec [NB_SIZE];
00120 static unsigned char nb_rec [NB_SIZE];
00121 static unsigned short px_rec [9*NB_SIZE];
00122 static unsigned char bit[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
00123
00124
00125
00126
00127 extern int adc1,adc2;
00128 extern int stat_blocks_sent;
00129 extern int com_scanmode;
00130 extern char input_skip_op;
00131 extern char skip_op;
00132 extern char keep_image;
00133 extern char do_xform;
00134 extern int fdnb;
00135 extern int stat_scan_add;
00136
00137 extern int edit_output;
00138 extern int nstrong;
00139 extern int nsat;
00140 extern CONFIG cfg;
00141
00142 extern "C" {
00143 extern int put_pck(unsigned short int*, int, int, int);
00144 extern void swaplong(char*, int);
00145 extern void swapshort(char*, int);
00146
00147
00148 extern int Putmar345Header (int, MAR345_HEADER);
00149 extern int Putmar300Header (int, int, MAR300_HEADER);
00150 extern MAR345_HEADER Getmar345Header (FILE *);
00151 extern MARNB_HEADER GetmarNBHeader (FILE *);
00152 extern int PutCIFHeader (char *, char *);
00153 extern int PutCIFData (char *, char *, char, unsigned int *);
00154 extern int GetCIFData (char *, char *, FILE *, unsigned int *);
00155 extern void mar3452CIFHeader(char *, char *, MAR345_HEADER );
00156 extern float GetResol(float, float, float);
00157 extern void rotate_i4 (unsigned int *, int);
00158 extern void rotate_i4_anti (unsigned int *, int);
00159 }
00160
00161 MarXF::MarXF(QObject *parent)
00162 : inherited(parent)
00163 {
00164 }
00165
00166
00167
00168
00169
00170 int
00171 MarXF::mar_start_scan_readout(int next_scan)
00172 {
00173 int i, i_pix;
00174 int swap[2];
00175 int j_dj[8] = { -1, 0, 1,-1, 1,-1, 0, 1};
00176 int i_di[8] = { -1,-1,-1, 0, 0, 1, 1, 1};
00177 extern char martable_dir[128];
00178 extern char nbcode_file[128];
00179
00180
00181
00182
00183 n1 = n2 = adcavg1 = adcavg2 = adcavg11= adcavg21= 0;
00184 adc_channel = 0;
00185 start_with_A = 1;
00186 bytes2xfer = 0;
00187 xform_status = 0;
00188 scan_in_progress = 1;
00189 xf_in_progress = 1;
00190 do_xform = 1;
00191 stat_xform_msg = 0;
00192 stat_blocks_sent = 0;
00193 current_pixel = 0;
00194 sp_pixels = 0;
00195 xf_pixels = 0;
00196 valmin = 999999;
00197 last_pixel = -1;
00198 last_block = -1;
00199 poff = 0;
00200 data_offset = 0;
00201 add_A = cfg.adcadd_A[ (int)stat_scanmode ];
00202 add_B = cfg.adcadd_B[ (int)stat_scanmode ];
00203 saturation = 1000000;
00204 stat_pixelsize = cfg.pixelsize[ (int)stat_scanmode ];
00205
00206 if ( strncmp( image_file, spiral_file, strlen(spiral_file) )== 0 )
00207 spiral_only = 1;
00208 else
00209 spiral_only = 0;
00210
00211 fdxf = 0;
00212
00213 if ( fdspiral >= 0 ) {
00214 close( fdspiral );
00215 fdspiral = -1;
00216 }
00217
00218
00219
00220
00221 spiral_offset = 0;
00222
00223
00224 if ( cfg.use_adc == 1 ) {
00225 spiral_offset = cfg.adcoff[(int)stat_scanmode];
00226 }
00227
00228 max_spiral_int = 0;
00229 istrong = 0;
00230 xf_rec = 0;
00231 iindex = 1024;
00232 nb_index = 0;
00233
00234
00235 ac_size = cfg.size[ (int)stat_scanmode ];
00236 total_pixels = ac_size * ac_size;
00237
00238
00239
00240
00241 if ( fpnb != NULL ) {
00242 fclose( fpnb );
00243 fpnb = NULL;
00244 }
00245
00246 if ( stat_scanmode > 3 ) {
00247 sprintf( nbcode_file,"%s/mar3450.%s", martable_dir, scanner_no);
00248 }
00249 else {
00250 sprintf( nbcode_file,"%s/mar2300.%s", martable_dir, scanner_no);
00251 }
00252
00253 if ( NULL == (fpnb = fopen( nbcode_file, "r" ))) {
00254 marError( 1100, 0 );
00255 do_xform = 0;
00256 keep_image = 0;
00257 }
00258
00259
00260
00261
00262
00263 nb = GetmarNBHeader( fpnb );
00264
00265
00266
00267
00268
00269 if ( nb.mode < 1 ) {
00270 marError( 1101, 0 );
00271 do_xform = 0;
00272 keep_image = 0;
00273 }
00274
00275
00276
00277
00278
00279 if ( nb.byteorder != 1234 ) {
00280 swap_nb = nb.byteorder;
00281 swap[0] = swap_nb;
00282 swaplong( (char*) swap, 4 );
00283 swap_nb = swap[0];
00284 nb.byteorder = 1234;
00285 if ( swap_nb != 1234 ) {
00286 marError( 1102, 0 );
00287 do_xform = 0;
00288 keep_image = 0;
00289 }
00290 swap_nb = 1;
00291 }
00292
00293
00294
00295
00296
00297
00298 if ( atoi( scanner_no ) != nb.scanner ) {
00299 marError( 1103, 0 );
00300 }
00301
00302
00303
00304
00305 i_rec = -1;
00306 for ( i=0; i<=4; i++ ) {
00307
00308 if ( nb.size[i] == ac_size ) {
00309 i_rec = nb.fpos[i];
00310 i_x0 = nb.x[i];
00311 j_y0 = nb.y[i];
00312 i_pix = nb.pixels[i];
00313 poff = nb.skip[i] + (int)cfg.toff[(int)stat_scanmode];
00314 nskip = poff-1;
00315 maximum_pixels = nb.pixels[i] + nb.skip[i];
00316 maximum_block = (int)(maximum_pixels/8192. + 0.999);
00317 maximum_bytes = maximum_block * 16386;
00318
00319
00320
00321
00322
00323 if ( nb.skip[i] % 2 != 0 ) {
00324 adc_channel = 1;
00325 start_with_A = 0;
00326 }
00327 break;
00328 }
00329 }
00330
00331
00332
00333
00334
00335
00336 if ( i_rec < 0 ) {
00337 marError( 1105, 0 );
00338 do_xform = 0;
00339 keep_image = 0;
00340 i_rec = 0;
00341 }
00342
00343
00344
00345
00346 if ( keep_image && !spiral_only ) {
00347
00348 sprintf( buf, "%s.tmp", image_file );
00349 if ( com_format == OUT_CIF || com_format == OUT_CBF ) {
00350 fdxf = 0;
00351 }
00352 else {
00353 fdxf = creat( buf, 0666 );
00354
00355 if ( fdxf == -1 ) {
00356 marError( 1110, 0 );
00357 do_xform = 0;
00358 fdxf = 0;
00359 }
00360
00361 else {
00362 close( fdxf );
00363 fdxf = 0;
00364 }
00365
00366
00367
00368
00369 fdxf = open( buf, O_RDWR );
00370 if( fdxf == -1 ) {
00371 marError( 1111, 0 );
00372 do_xform = 0;
00373 fdxf = 0;
00374 }
00375 }
00376 }
00377 else {
00378 if ( !spiral_only )
00379 do_xform = 0;
00380 keep_spiral = 1;
00381 }
00382
00383
00384 if ( keep_image == 0 ) {
00385 goto NEXT_1;
00386 }
00387
00388 for(i = 0; i < 8; i++)
00389 lin_dxy[i] = j_dj[i] * ac_size + i_di[i];
00390
00391
00392
00393
00394 if ( stat_scan_add == 0 ) {
00395 memset( (char *)u.i4_img, 0, sizeof(int)*total_pixels);
00396 }
00397 memset( (char *)xf_histo, 0, sizeof(int)*65600 );
00398
00399 for ( i=0; i<MAX_SIZE; i++ ) {
00400 i2_record[i] = 0;
00401 }
00402
00403 for ( i=0; i<MAX_SIZE/2; i++ ) {
00404 strong_rec[i].val = 0;
00405 strong_rec[i].add = 0;
00406 }
00407
00408
00409
00410
00411 NEXT_1:
00412 if ( do_xform )
00413 fseek( fpnb, i_rec, SEEK_SET);
00414
00415 if ( debug & 0x40 ) {
00416 fprintf(stdout,"\nscan345: transformation parameters:\n");
00417 fprintf(stdout,"\tCurrent scan mode: %d\n",stat_scanmode);
00418 fprintf(stdout,"\tStarting x: %d\n",i_x0);
00419 fprintf(stdout,"\tStarting y: %d\n",j_y0);
00420 fprintf(stdout,"\tSpiral offset: %d\n",poff);
00421 fprintf(stdout,"\tFirst rec at: %d\n",i_rec);
00422 fprintf(stdout,"\tNo. of pix/rec: %d\n",ac_size);
00423 fprintf(stdout,"\tTotal no. of pixels: %d\n",maximum_pixels);
00424 fprintf(stdout,"\tTotal no. of blocks: %d\n",maximum_block);
00425 }
00426 #ifdef DEBUG
00427 #endif
00428
00429
00430
00431
00432
00433
00434 if ( do_xform == 0 && keep_image == 1 ) {
00435 fprintf(stdout, "scan345: Image cannot be transformed!\n");
00436 fprintf(stdout, "scan345: Trying to write spiral files...!\n");
00437 keep_spiral = 1;
00438 }
00439
00440
00441
00442
00443 if ( do_xform == 1 && fdxf > 0 ) {
00444 if ( output_header( (int)1 ) != 1 ) {
00445 do_xform = 0;
00446 i = close( fdxf );
00447 keep_spiral = 1;
00448 fdxf = 0;
00449 }
00450 }
00451
00452
00453
00454
00455
00456 if ( output_header( 0 ) != 1 ) {
00457
00458
00459
00460
00461
00462
00463 if ( fdxf ) {
00464 i = close( fdxf );
00465 fdxf = 0;
00466 }
00467
00468 i = close(fdspiral);
00469 fdspiral = -1;
00470 return( 0 );
00471 }
00472
00473
00474
00475
00476 spiral_size = 4096 + maximum_block*16384;
00477
00478 return( 1 );
00479
00480 }
00481
00482
00483
00484
00485 void MarXF::Transform( int i_sp, int block_no, unsigned short *spiral )
00486 {
00487 register unsigned int adc,adcadd;
00488 register int sp_index, lin_pointer, nb_pointer;
00489 register int pixel_intensity;
00490 register int i;
00491
00492 static unsigned short *s_p;
00493 static unsigned char *n_p, nb_byte;
00494 static unsigned short *v_p;
00495 static signed char dx, dy, *x_p, *y_p;
00496
00497 int sp_offset;
00498 static int n_nb;
00499 double dtmp;
00500
00501
00502
00503
00504
00505
00506
00507
00508 if ( scan_in_progress == 0 || op_in_progress == 1 ) return;
00509
00510
00511
00512
00513
00514
00515 if ( poff > 0 ) {
00516 sp_offset = poff;
00517 if ( i_sp < poff ) {
00518 poff -= i_sp;
00519 current_pixel += i_sp;
00520 goto OUTPUT;
00521 }
00522 i_sp -= poff;
00523 poff = 0;
00524 current_pixel = nskip;
00525 }
00526 else
00527 sp_offset = 0;
00528
00529 last_block = stat_blocks_sent;
00530 last_pixel = current_pixel;
00531
00532
00533
00534
00535 if ( block_no <= 1 ) {
00536 adc1 = esd_stb.adc1;
00537 adc2 = esd_stb.adc2;
00538 }
00539
00540
00541
00542
00543
00544 #if ( __sgi111 || HPUX111 )
00545 swapshort( spiral+sp_offset, i_sp*sizeof(short) );
00546 #endif
00547
00548
00549 if (keep_spiral) {
00550 i = write(fdspiral, spiral+sp_offset, i_sp*sizeof(short) );
00551
00552 if ( i == -1 ) {
00553
00554 emit print_message(tr("scan345: Error writing spiral block %1\n").arg(stat_blocks_sent));
00555
00556 if ( do_xform == 0 ) {
00557 close( fdspiral );
00558 fdspiral = -1;
00559 xform_status = -1;
00560 return;
00561 }
00562 }
00563 if ( !keep_image )
00564 current_pixel += i_sp;
00565 }
00566
00567
00568 if ( sp_pixels == 0 ) {
00569 for ( i=0; i<2; i++ ) {
00570 spiral[i+sp_offset] = spiral[2+sp_offset];
00571 }
00572 }
00573
00574
00575
00576
00577
00578 #ifdef __osf__
00579 dtmp = block_no/(double)maximum_block;
00580 stat_xform_msg = (int)( 100*dtmp);
00581 #else
00582 stat_xform_msg = (int)( 100*(block_no/(float)maximum_block));
00583 stat_xform_msg = (int)( 100*(current_pixel/(float)maximum_pixels));
00584 #endif
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595 xform_status = 1;
00596
00597
00598 if ( do_xform == 0 ) {
00599 xform_status = 2;
00600 if ( last_pixel >= maximum_pixels ) {
00601 xform_status = 3;
00602 }
00603 }
00604
00605 if ( xform_status != 1 || sp_pixels >= maximum_pixels ) goto OUTPUT;
00606
00607
00608 s_p = spiral + sp_offset;
00609 sp_index = 0;
00610
00611
00612
00613
00614 NEXT_NB:
00615 if ( nb_index == 0 ) {
00616 if ( ( nb_index = ReadNB( fpnb ) ) < 1 ) {
00617 xform_status = 3;
00618 goto OUTPUT;
00619 }
00620
00621
00622 x_p = x_rec;
00623 y_p = y_rec;
00624 n_p = nb_rec;
00625 v_p = px_rec;
00626 n_nb = 0;
00627 }
00628
00629
00630
00631
00632
00633 while( sp_index < i_sp ) {
00634
00635
00636 if ( n_nb < 0 ) n_nb = 0;
00637 pixel_intensity = (int)*s_p;
00638 dx = *x_p;
00639 dy = *y_p;
00640 nb_byte = *n_p;
00641
00642
00643
00644
00645
00646 max0( max_spiral_int, pixel_intensity );
00647
00648
00649
00650
00651
00652 if ( pixel_intensity > cfg.spiral_max )
00653 pixel_intensity *= 100;
00654 else {
00655
00656 if ( cfg.use_adc ) {
00657 if ( adc_channel == 1 ) {
00658 adc = adc2;
00659 adcadd = add_B;
00660 }
00661 else {
00662 adc = adc1;
00663 adcadd = add_A;
00664 #ifdef DEBUG1
00665 n1++;
00666 adcavg1 += ( pixel_intensity - adc );
00667 adcavg11+= ( pixel_intensity - adc2);
00668 if ( n1 > 100000 ) {
00669 printf( "xxx n1=%8d \tavg1=%1.3f (%1.3f)\n", n1,adcavg1/(double)n1,adcavg11/(double)n1);
00670 n1 = adcavg1 = adcavg11= 0;
00671 }
00672 #endif
00673 }
00674
00675 pixel_intensity += (spiral_offset + adcadd - adc);
00676
00677 }
00678 else {
00679 if ( adc_channel == 1 )
00680 adcadd = add_B;
00681 else
00682 adcadd = add_A;
00683 pixel_intensity += adcadd;
00684 }
00685
00686 adc_channel = adc_channel ^ 0x01;
00687
00688 pixel_intensity *= cfg.spiral_scale;
00689 if ( pixel_intensity < 0 ) pixel_intensity = 0;
00690 }
00691
00692
00693
00694
00695
00696 fract_intens = pixel_intensity / nb.scale;
00697
00698
00699
00700
00701
00702 i_x0 += dx;
00703 j_y0 += dy;
00704
00705
00706
00707
00708
00709 lin_pointer = i_x0 * ac_size + j_y0 - 1;
00710
00711
00712
00713
00714
00715 if ( lin_pointer > 0 && lin_pointer <= total_pixels)
00716 ImageArray( lin_pointer, *v_p );
00717
00718
00719 v_p++;
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729 for(i = 0; i < 8; i++) {
00730
00731
00732 if ( (nb_byte & bit[i] ) == 0 ) continue;
00733
00734
00735 nb_pointer = lin_dxy[i] + lin_pointer;
00736 if ( nb_pointer>0 && nb_pointer<=total_pixels)
00737 ImageArray( nb_pointer, *v_p );
00738
00739
00740 v_p++;
00741 }
00742
00743
00744 sp_index++;
00745 sp_pixels++;
00746 current_pixel++;
00747
00748
00749 s_p++;
00750 x_p++;
00751 y_p++;
00752 n_p++;
00753
00754
00755 n_nb++;
00756 nb_index--;
00757
00758 if ( nb_index == 0 || n_nb >= NB_SIZE ) goto NEXT_NB;
00759
00760 if ( current_pixel >= maximum_pixels ) {
00761 xform_status = 3;
00762 goto OUTPUT;
00763 }
00764
00765 }
00766
00767 OUTPUT:
00768
00769
00770
00771 if ( xform_status == 3 || ( current_pixel >= maximum_pixels && stat_blocks_sent > 0) ) {
00772
00773 #ifdef DEBUG
00774 if ( debug & 0x80 )
00775 printf("debug (marxf): start of output image xf=%d current_pixel=%d (%d) block=%d\n",
00776 xform_status,current_pixel,maximum_pixels,stat_blocks_sent);
00777 #endif
00778
00779 if ( current_pixel < maximum_pixels ) {
00780 current_pixel = maximum_pixels;
00781 }
00782
00783 if (keep_spiral) {
00784 i = ltell( fdspiral );
00785 memset( (char *)spiral, 0, 8192);
00786 while ( ltell( fdspiral ) < spiral_size )
00787 i=write(fdspiral, spiral, 1*sizeof(short) );
00788 }
00789 output_image();
00790 }
00791
00792 return;
00793 }
00794
00795
00796
00797
00798 void MarXF::ImageArray( int addr, unsigned short i2_val)
00799 {
00800
00801
00802
00803
00804 u.i4_img[ addr ] = u.i4_img[ addr ] +
00805 (int) ( i2_val * fract_intens + 0.5 );
00806
00807 }
00808
00809
00810
00811
00812 void MarXF::output_image(void)
00813 {
00814 register unsigned int *i4_arr;
00815 register unsigned int i4_val;
00816 register unsigned int xx,yy;
00817 time_t now;
00818 float avgN,avgW,avgO,avgS;
00819 int k;
00820 unsigned int cenmax,cenmin,no, ns, reclen, len, i,j, nhist, pos;
00821 double Isum, diff;
00822
00823 #ifdef DEBUG
00824 if (debug & 0x40 )
00825 printf("debug (marxf): output image started %d\n",scan_in_progress);
00826 #endif
00827
00828 if ( scan_in_progress == 0 || op_in_progress ) return;
00829
00830 xf_in_progress = 0;
00831 op_in_progress = 1;
00832
00833 #ifdef FORMAT_TEST
00834 for ( istrong=0, i=0; i<80; i++ ) {
00835 pos = (i+605)*ac_size+500+i;
00836 for ( j=0; j<100; j++, pos++ ) {
00837 i4_val = 70000+i*10000+j*100;
00838 while ( i4_val > 65535 ) {
00839 if ( ch_image[pos] < 250 )
00840 ch_image[ pos ]++;
00841 i4_val -= 65535;
00842 }
00843 i2_image[ pos ] = i4_val;
00844 istrong++;
00845 }
00846 }
00847 #endif
00848 nstrong = istrong;
00849
00850
00851
00852
00853 if ( do_xform == 0 || keep_image == 0 ) {
00854 if ( keep_spiral )
00855 PrintResults( 0 );
00856 goto ALL_DONE;
00857 }
00858
00859
00860
00861
00862
00863
00864
00865 if ( com_format == OUT_IMAGE ) {
00866 rotate_i4( u.i4_img, ac_size );
00867 }
00868
00869
00870
00871
00872
00873 i4_arr = u.i4_img;
00874
00875
00876
00877
00878 cenmin = ac_size/2 - 5;
00879 cenmax = ac_size/2 + 5;
00880 Isum = 0.0;
00881 Imax = 0;
00882 nhist = 0;
00883 nsat = ns_rec = no = ns = 0;
00884
00885
00886
00887
00888
00889
00890
00891
00892 if ( com_format == OUT_MAR ) {
00893 reclen = 8;
00894 if ( fdxf )
00895 lseek(fdxf, 4096, SEEK_SET);
00896 }
00897 else {
00898 reclen = ac_size/4;
00899 if ( fdxf ) {
00900 if ( com_format == OUT_PCK )
00901 lseek(fdxf, 2*ac_size, SEEK_SET);
00902 else
00903 lseek(fdxf, 2*ac_size + 2*total_pixels, SEEK_SET);
00904 }
00905 }
00906
00907
00908
00909
00910 for ( i=j=0; i< total_pixels ; i++, i4_arr++ ) {
00911
00912 i4_val = *i4_arr;
00913
00914
00915
00916
00917
00918 if ( i4_val > Imax && i4_val < 250000 ) {
00919 xx = i%ac_size;
00920 yy = i/ac_size;
00921
00922 if ( xx<cenmin || xx >cenmax || yy<cenmin || yy > cenmax )
00923 Imax = i4_val;
00924 }
00925
00926
00927
00928
00929
00930 if ( i4_val > 0 && i4_val <= 65535 ) {
00931 Isum += i4_val;
00932 nhist++;
00933 xf_histo[ i4_val ]++;
00934 min0( valmin, (int)i4_val );
00935 }
00936
00937
00938
00939
00940
00941 if ( i4_val <= 65535 ) continue;
00942
00943
00944
00945
00946
00947 strong_rec[no].add = i;
00948 strong_rec[no].val = i4_val;
00949
00950
00951 if ( com_format == OUT_IMAGE || com_format == OUT_PCK )
00952 strong_rec[no].add++;
00953
00954
00955
00956
00957 if ( strong_rec[no].val > 250000 ) {
00958 nsat++;
00959 strong_rec[no].val = 999999;
00960 *i4_arr = 999999;
00961 }
00962 else {
00963 nhist++;
00964 xx = i%ac_size;
00965 yy = i/ac_size;
00966 if ( xx<cenmin || xx >cenmax || yy<cenmin || yy > cenmax )
00967 max0( Imax, strong_rec[no].val );
00968 Isum += strong_rec[no].val;
00969 }
00970
00971
00972
00973
00974
00975 no++;
00976 ns++;
00977
00978
00979
00980
00981 if ( no == reclen && do_xform && keep_image ) {
00982 ns_rec++;
00983 len = reclen*sizeof(STRONG);
00984 if ( fdxf ) {
00985 if ( write( fdxf, (char *)strong_rec, len) < len ) {
00986 marError( 1112, ltell( fdxf) );
00987 do_xform = 0;
00988 }
00989 }
00990 no = 0;
00991 }
00992 }
00993
00994
00995
00996
00997 if ( no > 0 && do_xform && keep_image && !spiral_only ) {
00998 for ( i=no; i<reclen; i++ ) {
00999 strong_rec[i].add = 0;
01000 strong_rec[i].val = 0;
01001 }
01002 ns_rec++;
01003 len = reclen*sizeof(STRONG);
01004 if ( fdxf ) {
01005 if ( write( fdxf, (char *)strong_rec, len) < len ) {
01006 marError( 1112, ltell( fdxf) );
01007 do_xform = 0;
01008 }
01009 }
01010 }
01011 if ( fdxf )
01012 pos = ltell( fdxf );
01013
01014
01015 if ( nhist > 0 )
01016 AvgI = Isum/(double)nhist;
01017 else
01018 AvgI = 0.0;
01019
01020
01021 i4_arr = u.i4_img;
01022 SigI = 0.0;
01023
01024
01025
01026
01027 for ( i=j=0; i< total_pixels ; i++, i4_arr++ ) {
01028 i4_val = *i4_arr;
01029 if ( i4_val == 0 ) continue;
01030 if ( i4_val > 250000 ) {
01031 if ( stat_scanmode < 4 )
01032 i4_val = 131072;
01033 else
01034 i4_val = 65535;
01035 }
01036 diff = i4_val - AvgI;
01037 diff *= diff;
01038 SigI += diff;
01039 j++;
01040 }
01041 if ( j>1 )
01042 SigI = sqrt( SigI/(double)(j - 1.0) );
01043
01044
01045
01046
01047
01048 if ( fdxf )
01049 if ( output_header( 1 ) != 1 ) {
01050 do_xform = 0;
01051 }
01052
01053 PrintResults( 1 );
01054
01055 if ( !do_xform ) goto ALL_DONE;
01056 if ( input_skip_op || skip_op || spiral_only ) goto SKIP1;
01057
01058 if ( cfg.use_stats && do_xform ) {
01059 j = (int)(cos( 3.14159 / 4.0 ) * (ac_size/2 - BOX_OFF) );
01060
01061
01062 xx = yy = ac_size/2. - BOXSIZE/2 - j;
01063
01064 avgW = PrintStats( 0, xx, yy, BOXSIZE, u.i4_img);
01065
01066
01067 xx = BOX_OFF - BOXSIZE/2;
01068 yy = ac_size/2 - BOXSIZE/2;
01069 avgW = PrintStats( 1, xx, yy, BOXSIZE, u.i4_img);
01070
01071
01072 xx = ac_size/2 - BOXSIZE/2;
01073 yy = BOX_OFF - BOXSIZE/2;
01074 avgN = PrintStats( 1, xx, yy, BOXSIZE, u.i4_img);
01075
01076
01077 xx = ac_size - BOXSIZE/2 - BOX_OFF;
01078 yy = ac_size/2 - BOXSIZE/2;
01079 avgO = PrintStats( 1, xx, yy, BOXSIZE, u.i4_img);
01080
01081
01082 xx = ac_size/2 - BOXSIZE/2;
01083 yy = ac_size - BOXSIZE/2 - BOX_OFF;
01084 avgS = PrintStats( 1, xx, yy, BOXSIZE, u.i4_img);
01085
01086 if ( avgO > 0.0 ) avgW /= avgO;
01087 else avgW = 0.0;
01088 if ( avgS > 0.0 ) avgN /= avgS;
01089 else avgN = 0.0;
01090
01091
01092
01093 avgW = 100.0-avgW*100.;
01094 avgN = 100.0-avgN*100.;
01095 if ( avgW < 0.0 )
01096 sprintf( str, "%8.3f" , avgW);
01097 else
01098 sprintf( str, " +%6.3f", avgW);
01099
01100 if ( avgN < 0.0 )
01101 sprintf( str, "%8.3f " , avgN);
01102 else
01103 sprintf( str, " +%6.3f ", avgN);
01104
01105 avgS = PrintStats(99, xx, yy, BOXSIZE, u.i4_img);
01106 }
01107
01108
01109
01110
01111 i=HistoMinMax();
01112
01113
01114
01115
01116
01117 if ( com_format == OUT_CIF || com_format == OUT_CBF ) {
01118
01119
01120 get_header_values( 1 );
01121 sprintf( str, "scan345 (V %s)",MAR_VERSION);
01122 mar3452CIFHeader( str, image_file, h345);
01123
01124
01125 if ( PutCIFHeader("scan345", image_file) < 1 ) {
01126 marError( 1115, 0 );
01127 do_xform = 0;
01128 }
01129 else {
01130
01131 i= PutCIFData( "scan345", image_file, (char)(com_format-OUT_CIF), u.i4_img);
01132 if ( i == 0 ) {
01133 marError( 1112, i );
01134 do_xform = 0;
01135 }
01136 }
01137
01138 }
01139
01140
01141 else {
01142 i4_arr = u.i4_img;
01143 for ( k=0; k<total_pixels ; k++) {
01144 i4_val = *i4_arr++;
01145 if ( i4_val > 65535 )
01146 u.i2_img[k] = 65535;
01147 else
01148 u.i2_img[k] = (unsigned short)i4_val;
01149 }
01150 }
01151
01152
01153
01154
01155
01156
01157
01158 if ( com_format == OUT_IMAGE ) {
01159
01160 lseek(fdxf, 2*ac_size, SEEK_SET);
01161
01162 j = write( fdxf, u.i2_img, 2*total_pixels );
01163 if ( (j < 2*total_pixels) == -1) {
01164 marError( 1112, j );
01165 do_xform = 0;
01166 }
01167 xf_pixels = j/2;
01168 }
01169
01170
01171
01172
01173
01174 else if ( com_format == OUT_MAR || com_format == OUT_PCK ) {
01175
01176
01177
01178 lseek(fdxf, pos , SEEK_SET);
01179
01180 sprintf(str,"\nCCP4 packed image, X: %04d, Y: %04d\n",ac_size,ac_size);
01181 if ( write(fdxf, str, strlen( str )) == -1 ) {
01182 marError( 1112, 2);
01183 }
01184
01185 j = put_pck( u.i2_img, ac_size, ac_size, fdxf );
01186
01187 if ( j == 0 ) {
01188 marError( 1112, 3);
01189 do_xform = 0;
01190 }
01191 }
01192
01193
01194 SKIP1:
01195
01196 if ( fdxf && ( com_format != OUT_IMAGE && com_format != OUT_PCK ) )
01197 i = output_header( 1 );
01198
01199
01200
01201
01202 ALL_DONE:
01203
01204
01205
01206
01207 if ( com_scan_add > 0 && do_xform && fdxf ) {
01208
01209
01210 k=total_pixels-1;
01211 while ( k>=0 ) {
01212 i4_val = (unsigned int)u.i2_img[k];
01213 u.i4_img[k] = i4_val;
01214 k--;
01215 }
01216
01217
01218 if ( com_format == OUT_IMAGE )
01219 lseek(fdxf, 2*ac_size + 2*total_pixels, SEEK_SET);
01220 else if ( com_format == OUT_PCK )
01221 lseek(fdxf, 2*ac_size, SEEK_SET);
01222 else
01223 lseek(fdxf, 4096, SEEK_SET);
01224
01225 for ( no=0; no<=nstrong; no++ ) {
01226 i = read(fdxf, strong_rec, 8 );
01227 if ( i != 8 ) {
01228 break;
01229 }
01230
01231 i = strong_rec[0].add;
01232 i4_val = strong_rec[0].val;
01233
01234
01235 if ( com_format != OUT_MAR ) i--;
01236
01237 if ( i < 0 || i >= (total_pixels-1) ) continue;
01238
01239 if ( i4_val < 65535 )
01240 continue;
01241 u.i4_img[i] = i4_val;
01242 }
01243
01244
01245 if ( com_format == OUT_IMAGE || com_format == OUT_PCK )
01246 rotate_i4_anti( u.i4_img, ac_size );
01247 }
01248
01249
01250
01251
01252 if ( keep_image && !spiral_only ) {
01253
01254 if ( fdxf ) {
01255 i = close( fdxf );
01256 fdxf = 0;
01257 }
01258 sprintf( buf, "%s.tmp", image_file );
01259
01260
01261 if ( input_skip_op || skip_op )
01262 remove( buf );
01263
01264
01265 else {
01266 rename( buf, image_file );
01267 strcpy( last_image, image_file );
01268 }
01269 }
01270 else if ( spiral_only ) {
01271 strcpy( last_image, image_file );
01272 }
01273
01274 scan_in_progress = do_xform = 0;
01275 op_in_progress = 0;
01276
01277
01278
01279
01280
01281 if (keep_spiral) {
01282 i = output_header( 0 );
01283 close(fdspiral);
01284
01285
01286 sprintf( buf, "%s.tmp", spiral_file );
01287 rename( buf, spiral_file );
01288
01289
01290 if ( cfg.use_image == 3 ) {
01291 sprintf( str, "packspiral %s &\n",spiral_file);
01292 system( str );
01293 }
01294 fdspiral = -1;
01295 }
01296
01297 #ifdef DEBUG
01298 if ( debug & 0x40 )
01299 printf("debug (marwh): output image all done\n");
01300 #endif
01301
01302
01303 time( &now );
01304
01305 emit print_message(QString().sprintf("scan345: OUTPUT IMAGE ENDED at %s",(char *)ctime( &now )));
01306 }
01307
01308
01309
01310
01311 int
01312 MarXF::output_header(int mode)
01313 {
01314 int i;
01315 int fd;
01316
01317
01318
01319 if ( mode == 0 && fdspiral < 0 ) {
01320
01321
01322
01323
01324
01325 if ( keep_spiral == 0 ) return( 1 );
01326
01327 sprintf( buf, "%s.tmp", spiral_file );
01328
01329 fdspiral = creat( buf, 0666 );
01330
01331 if ( fdspiral == -1 ) {
01332 marError( 1115, 0 );
01333 return( 0 );
01334 }
01335 else
01336 close( fdspiral );
01337
01338
01339
01340
01341
01342 fdspiral = open( buf, 2 );
01343
01344 if( fdspiral == -1 ) {
01345 marError( 1120, 0 );
01346 return( 0 );
01347 }
01348
01349
01350
01351 fd = fdspiral;
01352
01353 }
01354
01355 else if ( mode == 0 && fdspiral >= 0 ) {
01356
01357 fd = fdspiral;
01358 }
01359
01360
01361 else {
01362 if ( do_xform == 0 || keep_image == 0 || spiral_only ) return( 1 );
01363
01364 fd = fdxf;
01365 }
01366
01367
01368
01369
01370
01371 get_header_values( mode );
01372
01373
01374
01375
01376
01377 i = lseek( fd, 0, SEEK_SET );
01378
01379 if ( com_format == OUT_IMAGE || com_format == OUT_PCK ) {
01380 i = Putmar300Header( fd, nb.scanner, h300 );
01381 lseek( fd, 2*ac_size, SEEK_SET );
01382 }
01383 else {
01384 i = Putmar345Header( fd, h345 );
01385 lseek( fd, 4096, SEEK_SET );
01386 }
01387
01388
01389 if ( i < 1 ) {
01390 if ( mode == 0 )
01391 marError( 1121, 0 );
01392 else {
01393 marError( 1115, 0 );
01394 do_xform = 0;
01395 }
01396 return( 0 );
01397 }
01398
01399 return( (int)1 );
01400 }
01401
01402
01403
01404
01405 void
01406 MarXF::get_header_values(int mode)
01407 {
01408 time_t clock;
01409 extern int hist_begin, hist_end, hist_max;
01410 extern float op_dosebeg,op_doseend;
01411
01412
01413 memcpy( (char *)&h345.gap[0], (char *)stat_gap, 8*sizeof(int));
01414
01415
01416
01417
01418 h345.byteorder = 1234;
01419 h345.high = nstrong;
01420 h345.scanner = nb.scanner;
01421 h345.size = (short)ac_size;
01422 if ( com_format == OUT_IMAGE )
01423 h345.format = 0;
01424 else
01425 h345.format = 1;
01426 h345.mode = (char)com_mode;
01427 h345.high = nstrong;
01428 h345.pixels = ac_size*ac_size;
01429 h345.pixel_length = stat_pixelsize*1000.;
01430 h345.pixel_height = stat_pixelsize*1000.;
01431 h345.xcen = ac_size/2;
01432 h345.ycen = ac_size/2;
01433 h345.roff = cfg.roff[(int)stat_scanmode];
01434 h345.toff = cfg.toff[(int)stat_scanmode];
01435 h345.gain = 1.0;
01436 h345.time = com_time;
01437
01438 h345.dosebeg = com_dosebeg;
01439 h345.doseend = com_doseend;
01440 h345.dosemin = com_dosemin;
01441 h345.dosemax = com_dosemax;
01442 h345.doseavg = com_doseavg;
01443 h345.dosesig = com_dosesig;
01444 h345.dosen = com_dosen;
01445 h345.wave = com_wavelength;
01446
01447 if ( start_with_A ) {
01448 h345.adc_A = adc1;
01449 h345.adc_B = adc2;
01450 h345.add_A = add_A;
01451 h345.add_B = add_B;
01452 }
01453 else {
01454 h345.adc_A = adc2;
01455 h345.adc_B = adc1;
01456 h345.add_A = add_B;
01457 h345.add_B = add_A;
01458 }
01459
01460 h345.dist = com_dist;
01461 h345.resol = GetResol( (float)(ac_size*stat_pixelsize/2.0),
01462 (float)h345.dist,(float)h345.wave);
01463 h345.phibeg = com_phibeg;
01464 h345.phiend = com_phiend;
01465 h345.omebeg = com_omebeg;
01466 h345.omeend = com_omeend;
01467 h345.theta = com_theta;
01468 h345.chi = com_chi;
01469 h345.phiosc = com_phiosc;
01470 h345.omeosc = com_omeosc;
01471
01472 h345.valavg = AvgI;
01473 h345.valmin = valmin;
01474 h345.valmax = Imax;
01475 h345.valsig = SigI;
01476
01477 h345.histbeg = hist_begin;
01478 h345.histend = hist_end;
01479 h345.histmax = hist_max;
01480
01481 h345.multiplier = cfg.spiral_scale;
01482
01483
01484
01485
01486
01487 h345.polar = com_polar;
01488 h345.kV = com_kV;
01489 h345.mA = com_mA;
01490
01491 strcpy( h345.version, MAR_VERSION );
01492 strcpy( h345.program, "scan345 (ESD)" );
01493
01494 strcpy( h345.source, com_source );
01495 strcpy( h345.filter, com_filter );
01496 strcpy( h345.remark, com_remark );
01497
01498 time( &clock );
01499 sprintf( str, "%s",(char *) ctime(&clock) );
01500 memcpy( h345.date, str, 24 );
01501 memcpy( h300.date, str, 24 );
01502
01503
01504 if ( mode == 0 ) {
01505 if ( stat_scanmode > 3 )
01506 h345.pixel_length = stat_pixelsize*500.;
01507 h345.pixels = maximum_pixels - poff;
01508 h345.format = 2;
01509 }
01510
01511
01512
01513
01514 h300.pixels_x = ac_size;
01515 h300.pixels_y = ac_size;
01516 h300.lrecl = 2*ac_size;
01517 h300.max_rec = ac_size+1;
01518 h300.high_pixels = h345.high;
01519 h300.high_records = ns_rec;
01520 h300.counts_start = (int)op_dosebeg;
01521 h300.counts_end = (int)op_doseend;
01522 h300.exptime_sec = stat_time;
01523 h300.exptime_units = (int)sum_xray_units;
01524 h300.prog_time = com_time;
01525 h300.r_max = cfg.diameter[stat_scanmode]/2.;
01526 h300.r_min = 0;
01527 h300.p_r = nb.pixel_height;
01528 h300.p_l = nb.pixel_length;
01529 h300.p_x = nb.pixel_height;
01530 h300.p_y = nb.pixel_height;
01531 h300.centre_x = h345.xcen;
01532 h300.centre_y = h345.ycen;
01533 h300.lambda = h345.wave;
01534 h300.distance = h345.dist;
01535 h300.phi_start = h345.phibeg;
01536 h300.phi_end = h345.phiend;
01537 h300.omega = h345.omebeg;
01538 h300.multiplier = h345.multiplier;
01539 }
01540
01541
01542
01543
01544 void
01545 MarXF::PrintResults( int mode )
01546 {
01547
01548
01549
01550
01551 if ( mode == 1 && !(input_skip_op || skip_op ) )
01552 sprintf( str, " -> File: %s\n", image_file);
01553 else {
01554 if ( spiral_only )
01555 sprintf( str, " -> File: %s\n", spiral_file);
01556 else
01557 sprintf( str, " !!! -> File: %s\n", spiral_file);
01558 }
01559
01560 emit print_message(str);
01561
01562 if ( mar_cmd != MDC_COM_SCAN ) {
01563 sprintf( str, " Phi range [degrees]: %8.3f --> %1.3f\n",com_phibeg,com_phiend);
01564 if ( cfg.use_phi ) {
01565 emit print_message(str);
01566 }
01567 sprintf( str, " Exposure time [sec]: %8.0f\n",com_time);
01568 emit print_message(str);
01569
01570 #ifdef MAR345
01571 sprintf( str, " Average X-ray intensity: %8.2f\n", sum_xray_units);
01572 emit print_message(str);
01573 #endif
01574 }
01575
01576 if ( mode != 0 || input_skip_op || skip_op || spiral_only ) {
01577
01578 if ( cfg.use_stats ) {
01579 sprintf( str, " Average image intensity: %8.1f\n",AvgI);
01580 emit print_message( str );
01581 }
01582 sprintf( str, " Maximum valid intensity: %8d\n", Imax );
01583 emit print_message( str );
01584 sprintf( str, " No. of pixels > 65535: %8d\n",nstrong);
01585 if ( istrong > 0 ) {
01586 emit print_message( str );
01587 }
01588 sprintf( str, " No. of saturated pixels: %8d\n",nsat);
01589 if ( nsat > 0 ) {
01590 emit print_message( str );
01591 }
01592 }
01593 }
01594
01595
01596
01597
01598 int
01599 MarXF::ReadNB(FILE *fp)
01600 {
01601 int i,n,n_nb;
01602 unsigned short r_rec[4];
01603 static int n_rec=0;
01604
01605
01606 i = fread( (unsigned short *)r_rec, sizeof(short), 2, fp );
01607
01608 if (swap_nb) swapshort((char*) r_rec, 2*sizeof(short) );
01609
01610 n = r_rec[0];
01611 n_nb = r_rec[1];
01612
01613
01614 i += fread( x_rec, sizeof(char), n, fp );
01615
01616
01617 i += fread( y_rec, sizeof(char), n, fp );
01618
01619
01620 i += fread(nb_rec, sizeof(char), n, fp );
01621
01622 if ( i != (3*n+2) ) {
01623
01624
01625
01626 return( 0 );
01627 }
01628
01629
01630 if ( n_nb > 0 ) {
01631 i = fread( px_rec, sizeof(unsigned short), n_nb, fp );
01632
01633 if (swap_nb) swapshort( (char*) px_rec, n_nb*sizeof(short) );
01634
01635 if ( i != n_nb ) {
01636 fprintf( stdout, "scan345: ERROR reading nb at pixel %d in record %ld\n",sp_pixels+1,ftell(fp) );
01637 return( 0 );
01638 }
01639 }
01640
01641 n_rec++;
01642
01643 return( n );
01644 }
01645
01646
01647
01648
01649 float
01650 MarXF::PrintStats( int mode, int x, int y, int NP, unsigned int *i4_arr)
01651 {
01652 register unsigned int i,j,*i4;
01653 register unsigned int i4_val;
01654 static time_t now,last=0 ;
01655 struct tm *time_ptr;
01656 int n, k,l;
01657 double diff,sum,avg,sig;
01658 char clock_time[32];
01659
01660
01661 if ( mode == 99 ) {
01662 now = time( NULL );
01663 time_ptr= localtime( &now);
01664 n = now - last;
01665 if ( last==0 ) n = 0;
01666
01667
01668 strftime( clock_time, 16, "%a %H:%M.%S", time_ptr );
01669
01670 sprintf( str, "%s%5d%6d%6.1f%6.1f %s\n",
01671 clock_time,n,stat_gap[0],adc1/1000.,adc2/1000.,image_file);
01672
01673 last = now;
01674 return(1.0);
01675 }
01676
01677 sig = sum = avg = 0.0;
01678
01679 for ( i=k=l=0; i<NP; i++ ) {
01680 n = ac_size*( y+i ) + x;
01681 i4 = i4_arr + n ;
01682 for ( j=0; j<NP; j++, i4++ ) {
01683 i4_val = *i4;
01684 if ( i4_val == 0 || i4_val > 250000 ) {
01685 continue;
01686 }
01687 k++;
01688 sum += i4_val;
01689 }
01690 }
01691 sig = 0.0;
01692
01693 if ( k > 1 )
01694 avg = sum/(double)k;
01695 else
01696 return( avg);
01697
01698 for ( i=0; i<NP; i++ ) {
01699 n = ac_size*( y+i ) + x;
01700 i4 = i4_arr + n ;
01701 for ( j=0; j<NP; j++, i4++ ) {
01702 i4_val = *i4;
01703 if ( i4_val == 0 || i4_val > 250000 ) continue;
01704 diff = i4_val - avg;
01705 diff *= diff;
01706 sig += diff;
01707 }
01708 }
01709
01710 sig = sqrt( sig/(double)(k - 1.0) );
01711
01712 if ( mode == 0 ) {
01713 sprintf( str, "%7.1f%6.1f", avg, sig);
01714 }
01715
01716 return avg;
01717 }
01718
01719
01720
01721
01722 int
01723 MarXF::HistoMinMax(void)
01724 {
01725 register int *hist=xf_histo;
01726 register int i;
01727 float dh, hsumr, hsuml;
01728
01729
01730
01731
01732
01733 hsuml=hist_max=0;
01734 for (i=1; i<=65535; i++ ) {
01735 hsuml = hsuml + hist[i];
01736 max0( hist_max, hist[i] );
01737 }
01738
01739
01740
01741
01742 hist_begin = 0;
01743 hsumr = 0;
01744 for (i=65535; i>0; i-- ) {
01745 hsumr = hsumr + hist[i];
01746 hsuml = hsuml - hist[i];
01747 if (hsuml>(float)0.0) dh = hsumr/hsuml;
01748 if (dh>0.002) break;
01749 }
01750
01751 hist_end = i;
01752
01753 if (hist_end < 250) hist_end = 250;
01754
01755 return( hist_end );
01756
01757 }