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 <time.h>
00023 #include <math.h>
00024 #include <string.h>
00025 #include <errno.h>
00026 #include <signal.h>
00027 #include <stdlib.h>
00028 #include <unistd.h>
00029
00030 #include "esd.h"
00031 #include "esd_error.h"
00032 #include "marcmd.h"
00033 #include "mar_command.h"
00034 #include "marglobals.h"
00035 #include "twopower.h"
00036 #include "config.h"
00037
00038 #include "marhw.h"
00039
00040 #define min0(a,b) if ( b < a ) a = b
00041 #define max0(a,b) if ( b > a ) a = b
00042 #define MAX_DOSE 2000
00043
00044
00045
00046 char start_time[32];
00047 char motor_op = 0;
00048 char skip_op = 0;
00049 char keep_image = 1;
00050 int mar_error = 0;
00051 int target_steps = 0;
00052 int ict1 = 0;
00053 int ict2 = 0;
00054 int adc1 = 0;
00055 int adc2 = 0;
00056
00057 time_t exposure_time;
00058 time_t exposure_start = 0;
00059 int erase_start;
00060
00061 int fehler_index = 0;
00062 int stat_scan_add = 0;
00063 int stat_task_number;
00064 int stat_task_active;
00065 int stat_task_done;
00066 int stat_task_mode;
00067 int stat_task_error;
00068 int stat_pixels;
00069 int stat_blocks_sent;
00070 int stat_blocks_scanned;
00071 int stat_reference_status;
00072 int stat_plate_locked;
00073 int stat_lock_permit;
00074 int stat_sending_data;
00075 int stat_oscil_msg = (-1);
00076 char stat_home = 1;
00077 char stat_scan_active = 0;
00078 int com_phi_steps;
00079
00080 int op_dosen;
00081 float op_dosebeg,op_doseend,op_dosemin,op_dosemax;
00082 float op_doseavg,op_dosesig;
00083 double target_distance, original_distance;
00084 double target_phi, original_phi;
00085 double target_omega, original_omega;
00086
00087 static float expo_dosebeg = 99999;
00088 static float expo_doseend = 0.0;
00089 static float expo_doseavg = 0.0;
00090 static float expo_dosesig = 0.0;
00091 static float expo_dosemin = 999999.0;
00092 static float expo_dosemax = 0.0;
00093 static int expo_dosen = 0;
00094
00095
00096
00097
00098 static int i, j;
00099
00100 static char motor_moving[6] = {0,0,0,0,0,0};
00101 static char change_mode =0;
00102 static char scan_started =0;
00103 static char stop_image =0;
00104
00105 static int last_mar_mode =0;
00106 static int dist_retry =0;
00107 static int intensity_counter =0;
00108 static int open_shutter_counter =0;
00109 static int close_shutter_counter =0;
00110 static int scan_error =0;
00111 static int p_task_active =0;
00112 static int erase_lamps_ok =0;
00113 static int expo_dose[MAX_DOSE];
00114 static time_t now,tick;
00115 static time_t last=0;
00116 static float ftmp;
00117 static float erase_time=1.0;
00118 static float xray_start = -999.0;
00119 static float stat_start_phi = 0.0;
00120
00121 static int stat_erase_T,stat_erase_R,stat_erase_L;
00122 static int stat_erase_T_temp,stat_erase_R_temp,stat_erase_L_temp;
00123 static int stat_servo_warning,stat_laser_status;
00124 static int task_done [MAX_CMD];
00125 static int task_error [MAX_CMD];
00126 static int task_active [MAX_CMD];
00127 static int task_queued [MAX_CMD];
00128 static int task_started [MAX_CMD];
00129
00130
00131
00132
00133
00134 extern char op_in_progress;
00135 extern char scan_in_progress;
00136 extern int images_per_sweep;
00137 extern int current_block,maximum_block;
00138 extern int current_pixel;
00139 extern int maximum_pixels;
00140
00141
00142
00143
00144 extern "C" {
00145 float GetDiskSpace(char*);
00146 int mar_io();
00147 void swaplong(char*, int);
00148 }
00149
00150 static MarHW* marhw=NULL;
00151
00152 MarHW::MarHW(QObject *parent)
00153 : inherited(parent),
00154 p_counter(-1)
00155 {
00156 marhw=this;
00157 }
00158
00159 void
00160 MarHW::restart()
00161 {
00162 p_counter = -1;
00163 }
00164
00165 MarHW* MarHW::mar_hw()
00166 {
00167 return marhw;
00168 }
00169
00170
00171
00172
00173 void MarHW::mar_abort(int)
00174 {
00175 int i;
00176 emit mar_hw()->print_message("scan345: Trying to abort current task ...\n");
00177
00178 i=mar_hw()->marTask( MDC_COM_ABORT, 1.0);
00179
00180
00181 signal( SIGQUIT, mar_abort);
00182 }
00183
00184
00185
00186
00187 int
00188 MarHW::mar_command()
00189 {
00190
00191 if ( netcontrol==0 ) return( 0 );
00192 time( &now );
00193
00194 emit print_message(QString("scan345: Task %1 STARTED at %2\n").arg(cmdstr[mar_number]).arg((char *)ctime( &now )));
00195 fflush( stdout );
00196
00197 esd_cmd.cmd = mar_number;
00198 esd_cmd.mode = mar_mode;
00199 esd_cmd.par1 = mar_par1;
00200 esd_cmd.par2 = mar_par2;
00201 esd_cmd.par3 = mar_par3;
00202 esd_cmd.par4 = mar_par4;
00203 esd_cmd.par5 = mar_par5;
00204
00205 strcpy( esd_cmd.id , "IPS" );
00206 if ( mar_number != CMD_SHELL ) mar_str[0]= '\0';
00207
00208 strcpy( esd_cmd.str, mar_str );
00209
00210 if ( verbose )
00211 emit print_message(
00212 QString().sprintf( "scan345: IPS %d %d %d %d %d %d %d %s\n",
00213 mar_number,mar_mode,mar_par1,mar_par2,mar_par3,mar_par4,mar_par5,mar_str));
00214 if ( net_comm( (int)1, (char *)&esd_cmd ) < 1 ) {
00215 marError( 1000, mar_number);
00216 return( 0 );
00217 }
00218
00219 last_mar_mode = mar_mode;
00220
00221 return 1;
00222 }
00223
00224
00225
00226
00227 int
00228 MarHW::mar_move_phi(double d)
00229 {
00230
00231 double delta;
00232 int wanted,nsteps_to_move;
00233
00234 if ( dc_stop > 1 )
00235 return( 1 );
00236
00237
00238
00239 delta = com_phibeg;
00240
00241 while (delta < 0.0) delta += 360.;
00242 while (delta >= 360.0) delta -= 360.;
00243
00244 target_phi = delta;
00245
00246
00247 if( !cfg.use_phi ) {
00248 stat_phi = delta;
00249 i = mar_start_expo();
00250 return( 1 );
00251 }
00252
00253 wanted = (delta + 0.5 * (1. / cfg.phi_steps)) * cfg.phi_steps;
00254
00255 nsteps_to_move = wanted - phi_steps;
00256
00257 if ( d > -9999. ) {
00258 if ( d < 0.0 )
00259 nsteps_to_move = wanted = ( d - 0.5 * (1. / cfg.phi_steps)) * cfg.phi_steps;
00260 else
00261 nsteps_to_move = wanted = ( d + 0.5 * (1. / cfg.phi_steps)) * cfg.phi_steps;
00262 }
00263
00264 while ( abs(nsteps_to_move) > 180 * cfg.phi_steps) {
00265 if(nsteps_to_move < 0)
00266 nsteps_to_move += 360 * cfg.phi_steps;
00267 else
00268 nsteps_to_move -= 360 * cfg.phi_steps;
00269 }
00270
00271
00272 if(nsteps_to_move == 0) {
00273
00274 i = mar_start_expo( );
00275 return( 1 );
00276 }
00277
00278 else if ( nsteps_to_move < 0 ) {
00279 nsteps_to_move -= 125;
00280 mar_par4 = 125;
00281 mar_par5 = cfg.phi_speed/2;
00282 }
00283 else {
00284 mar_par4 = 0;
00285 mar_par5 = cfg.phi_speed;
00286 }
00287
00288
00289 stat_scanner_op = CMD_MOVE_PHI;
00290 motor_op = stat_scanner_op;
00291
00292 mar_number = CMD_MOVE;
00293 mar_mode = ARG_PHI;
00294 mar_par1 = ARG_MOVE_REL;
00295 mar_par2 = nsteps_to_move;
00296 mar_par3 = cfg.phi_speed;
00297 mar_str[0] = '\0';
00298
00299 if( 0 == mar_command( )) return( -1 );
00300
00301 return( 1 );
00302 }
00303
00304
00305
00306 void
00307 MarHW::mar_quit(int m)
00308 {
00309 static char call=0;
00310
00311 if ( call > 0 ) {
00312
00313 exit(0);
00314 }
00315
00316
00317 mar_number = CMD_ION_CHAMBER;
00318 mar_mode = ARG_ENABLE;
00319 mar_par1 = mar_par2 = 0;
00320 i = mar_command();
00321 sleep( 1 );
00322
00323
00324 i = Modulo360();
00325
00326
00327 for ( i=0; i<4; i++ ) {
00328 net_close( i );
00329 }
00330
00331 emit print_message("scan345: Sockets have been closed! No more scanner control...\n");
00332 call = 1;
00333
00334 exit( 0 );
00335 }
00336
00337
00338
00339
00340 int
00341 MarHW::mar_change_mode()
00342 {
00343 int i;
00344 static int previous_mode= 99;
00345
00346
00347 if ( netcontrol == 0 || change_mode == 0 || cur_mode == previous_mode || cur_mode == stat_scanmode ){
00348
00349 if ( mar_cmd != MDC_COM_MODE && mar_cmd != MDC_COM_STARTUP ) {
00350
00351
00352 sprintf(str,"scan345: Diameter increased for next scan mode!\nscan345: Plate will be erased first ...\n");
00353 if ( mar_cmd != MDC_COM_ERASE )
00354 emit print_message(str);
00355
00356 i = mar_erase();
00357 return 1;
00358 }
00359 }
00360
00361
00362 previous_mode = cur_mode;
00363 stat_scanner_msg= 0;
00364 stat_scanner_op = CMD_CHANGE;
00365
00366
00367 mar_number = CMD_CHANGE;
00368 mar_mode = cur_mode+1;
00369 mar_par1 = mar_par2 = mar_par3 = mar_par4 = mar_par5 = 0;
00370 mar_str[0] = '\0';
00371
00372 mar_command() ;
00373
00374 return 1;
00375 }
00376
00377
00378
00379
00380 int
00381 MarHW::mar_erase()
00382 {
00383 int i;
00384
00385 if ( netcontrol == 0 ) return 1;
00386
00387 if ( mar_cmd == MDC_COM_SCAN ) {
00388 i = StartScan();
00389 return 1;
00390 }
00391
00392
00393 erase_start = time(NULL);
00394 erase_time = cfg.erasetime[ stat_scanmode ];
00395 stat_scanner_op = CMD_ERASE;
00396 stat_scanner_msg= 0;
00397
00398
00399 mar_number = CMD_ERASE;
00400 mar_mode = stat_scanmode+1;
00401 mar_par1 = mar_par2 = mar_par3 = mar_par4 = mar_par5 = 0;
00402 mar_str[0] = '\0';
00403
00404 i= mar_command();
00405
00406 return 1;
00407 }
00408
00409
00410
00411
00412 int
00413 MarHW::NotEnoughDiskSpace()
00414 {
00415 int i;
00416 float disk,dfree;
00417
00418
00419
00420
00421 dfree = GetDiskSpace( stat_dir );
00422 i = cfg.size[ run_p[SET].scanmode ];
00423 disk = (i*i*2 + 2*i)/1000000.;
00424
00425 if ( ( com_format == OUT_PCK || com_format == OUT_MAR ||
00426 com_format == OUT_CBF || com_format == OUT_CIF ) && keep_image )
00427 disk *= 0.5;
00428
00429
00430 if ( keep_spiral )
00431 disk += (i*i*2 + 2*i)/1000000.;
00432
00433 if ( disk > dfree ) {
00434
00435 sprintf( str, "scan345: Disk %s is full!\n", stat_dir );
00436 emit print_message(str);
00437
00438
00439 if ( disk < dfree ) {
00440 strcpy( stat_dir, working_dir );
00441 sprintf( str, "scan345: Continue to write data into %s\n", stat_dir );
00442 emit print_message(str);
00443 }
00444 }
00445
00446 return 0;
00447 }
00448
00449
00450
00451
00452 int
00453 MarHW::marTask(int task, float val )
00454 {
00455 int wanted,nsteps_to_move;
00456 struct tm *cur_time;
00457 char curtime[16];
00458 int i,sys_param[5] = { 279, 97, 278, 95, 0 };
00459 double delta;
00460 extern char input_keep_spiral;
00461 extern char input_keep_image ;
00462
00463 dc_stop = 0;
00464 stat_scanner_control = MAR_CONTROL_ACTIVE;
00465
00466
00467 if ( task != MDC_COM_SHELL && task != MDC_COM_IPS ) {
00468 mar_number = mar_mode = 0;
00469 mar_par1 = mar_par2 = 0;
00470 mar_par3 = mar_par4 = 0;
00471 mar_par5 = 0;
00472 mar_str[0] = '\0';
00473 }
00474
00475 switch( (int)task ) {
00476
00477 case MDC_COM_IDLE:
00478 if( 0 == mar_command( )) return( 0 );
00479 break;
00480
00481 case MDC_COM_IPS:
00482 mar_cmd = MDC_COM_IPS;
00483 if( 0 == mar_command( )) return( 0 );
00484 break;
00485
00486 case MDC_COM_SHELL:
00487 mar_cmd = MDC_COM_SHELL;
00488 mar_number = CMD_SHELL;
00489 mar_mode = 0;
00490 mar_par1 = 0;
00491 mar_par2 = 0;
00492 mar_par3 = 0;
00493 mar_par4 = 0;
00494 mar_par5 = 0;
00495 strcpy( mar_str, ips_command );
00496 if( 0 == mar_command( )) return( 0 );
00497 break;
00498
00499 case MDC_COM_RESTART:
00500 return( 1 );
00501 break;
00502
00503 case MDC_COM_QUIT:
00504 mar_quit(0);
00505 return( 1 );
00506 break;
00507
00508 case MDC_COM_STARTUP:
00509 case MDC_COM_INIT:
00510 mar_cmd = MDC_COM_INIT;
00511 stop_image = 0;
00512 target_distance = val;
00513
00514
00515 if ( stat_xray_shutter == SHUTTER_IS_OPEN ) {
00516 mar_cmd = (int)task;
00517 stat_scanner_op = CMD_SHUTTER;
00518 mar_number = CMD_SHUTTER;
00519 mar_mode = ARG_CLOSE;
00520 if( 0 == mar_command( )) return( 0 );
00521 sleep ( 1 );
00522 }
00523
00524 if ( task == MDC_COM_STARTUP ) {
00525 mar_cmd = MDC_COM_STARTUP;
00526
00527 if ( esd_stb.task[CMD_SCAN] & 0x02 ) {
00528 emit print_message("scan345: Task SCAN found active ...\n");
00529 emit print_message("scan345: Please wait and restart program after SCAN has finished!\n");
00530 mar_quit( 0 );
00531 exit( 0 );
00532 }
00533
00534
00535 for ( i=13; i<13; i++ ) {
00536 if ( esd_stb.task[i] & 0x02 ) {
00537 sprintf( str, "scan345: Task %2d found active ...\n",i );
00538 emit print_message(str);
00539 if ( i == CMD_MOVE ) {
00540 for ( j=0; j<6; j++ ) {
00541 if ( motor_moving[j] == 0 || (j+1)==ARG_RADIAL ) continue;
00542
00543 mar_number = CMD_ABORT;
00544 mar_mode = i;
00545 mar_par1 = 0;
00546 if( 0 == mar_command( )) return( 0 );
00547 sleep( 1 );
00548 }
00549 }
00550 else {
00551 mar_number = CMD_ABORT;
00552 mar_mode = i;
00553 if( 0 == mar_command( )) return( 0 );
00554 sleep( 1 );
00555 }
00556 }
00557 }
00558
00559 time( &now );
00560 cur_time = localtime( &now );
00561
00562
00563 mar_number = CMD_SHELL;
00564 strftime( curtime, 16, "%H:%M:%S", cur_time);
00565 sprintf ( mar_str, "clockset %s\r", curtime);
00566 if( 0 == mar_command( )) return( 0 );
00567 sleep( 1 );
00568
00569 strftime( curtime, 16, "%d-%m-%Y", cur_time);
00570 sprintf ( mar_str, "dateset %s\r", curtime);
00571 if( 0 == mar_command( )) return( 0 );
00572 sleep( 1 );
00573
00574
00575 mar_number = CMD_ION_CHAMBER;
00576 mar_mode = ARG_ENABLE;
00577 if( 0 == mar_command( )) return( 0 );
00578
00579
00580
00581 for ( i=0; i<4; i++ ) {
00582 mar_number = CMD_SET;
00583 mar_mode = ARG_READ;
00584 mar_par1 = sys_param[ i ];
00585 if( 0 == mar_command( )) return( 0 );
00586 sleep( 1 );
00587 }
00588
00589
00590 if ( esd_stb.servo_state != 0 ) {
00591 emit print_message("scan345: Initializing SERVO system ...\n");
00592 sprintf ( mar_str, "SERVO_INIT 1,3,5\r");
00593 if( 0 == mar_command( )) return( 0 );
00594 sleep( 1 );
00595 i = mar_servo();
00596 break;
00597 }
00598
00599 mar_lock();
00600
00601
00602 if ( esd_stb.scanmode > 0 && esd_stb.scanmode < 9 ) {
00603
00604 i = Modulo360();
00605 }
00606
00607
00608 sprintf( str, "scan345: Current scan mode: %d ...\n", stat_scanmode );
00609 emit print_message(str);
00610
00611 break;
00612 }
00613
00614 mar_number = CMD_MOVE;
00615 mar_mode = ARG_DISTANCE;
00616 if (target_distance == cfg.dist_max) {
00617 mar_par1 = ARG_INIT_FAR;
00618 mar_par2 = (cfg.dist_max + 0.5 * (1. / cfg.dist_steps)) * cfg.dist_steps;
00619 }
00620 else {
00621 mar_par1 = ARG_INIT_NEAR;
00622 mar_par2 = (cfg.dist_min + 0.5 * (1. / cfg.dist_steps)) * cfg.dist_steps;
00623 }
00624 mar_par3 = cfg.dist_speed;
00625 mar_par4 = 0;
00626 mar_par5 = cfg.dist_speed/10;
00627 if( 0 == mar_command( )) return( 0 );
00628
00629 stat_scanner_op = CMD_MOVE_DISTANCE;
00630 motor_op = stat_scanner_op;
00631
00632 break;
00633
00634 case MDC_COM_ABORT:
00635
00636
00637 if ( scan_in_progress && ( stat_task_number == CMD_SCAN || stat_task_number == CMD_ERASE ) ) {
00638 break;
00639 }
00640
00641
00642 mar_number = CMD_ABORT;
00643 mar_par1 = mar_par2 = 0;
00644 for ( i=j=0; j<6; j++ ) {
00645 if ( motor_moving[j] == 0 || (j+1)==ARG_RADIAL ) continue;
00646
00647 if ( (j+1) == ARG_DISTANCE ) {
00648 sprintf( str ,"scan345: Abort DRIVE DETECTOR\n");
00649 if ( stat_scanner_op != CMD_MOVE_DISTANCE ) continue;
00650 }
00651 else if ( (j+1) == ARG_OMEGA ) {
00652 sprintf( str ,"scan345: Abort DRIVE OMEGA\n");
00653 if ( stat_scanner_op != CMD_MOVE_OMEGA ) continue;
00654 }
00655 else if ( (j+1) == ARG_CHI ) {
00656 sprintf( str ,"scan345: Abort DRIVE CHI\n");
00657 if ( stat_scanner_op != CMD_MOVE_CHI) continue;
00658 }
00659 else if ( (j+1) == ARG_THETA ) {
00660 sprintf( str ,"scan345: Abort DRIVE THETA\n");
00661 if ( stat_scanner_op != CMD_MOVE_THETA ) continue;
00662 }
00663 else if ( (j+1)== ARG_PHI ) {
00664 sprintf( str ,"scan345: Abort DRIVE PHI\n");
00665 if ( stat_scanner_op != CMD_MOVE_PHI ) continue;
00666 }
00667
00668 emit print_message(str);
00669
00670 mar_number = CMD_ABORT;
00671 mar_mode = CMD_MOVE;
00672 mar_par1 = 0;
00673 dc_stop = 2;
00674
00675 if( 0 == mar_command( )) return( 0 );
00676 i++;
00677
00678 if ( (j+1) == ARG_PHI ) {
00679
00680 Modulo360();
00681 }
00682
00683 }
00684 if ( mar_cmd != MDC_COM_COLL) break;
00685
00686 emit print_message("\nscan345: Abort EXPOSURE\n");
00687
00688
00689 mar_number = CMD_ABORT;
00690 mar_mode = CMD_COLLECT;
00691
00692 if( 0 == mar_command( )) return( 0 );
00693
00694
00695 Modulo360();
00696
00697 break;
00698
00699 case MDC_COM_SHUT:
00700 mar_cmd = (int)task;
00701 stat_scanner_op = CMD_SHUTTER;
00702 mar_number = CMD_SHUTTER;
00703 mar_par1 = mar_par2 = 0;
00704
00705 if( val == 1.0 ) {
00706 mar_mode = ARG_OPEN;
00707 }
00708
00709 else {
00710 mar_mode = ARG_CLOSE;
00711 }
00712
00713 if( 0 == mar_command( )) return( 0 );
00714 break;
00715
00716 case MDC_COM_CHAMBER:
00717 stop_image = 0;
00718 dc_stop = 0;
00719 mar_number = CMD_ION_CHAMBER;
00720 mar_par1 = mar_par2 = 0;
00721
00722 if( val == 1.0 )
00723 mar_mode = ARG_ENABLE;
00724
00725 else
00726 mar_mode = ARG_DISABLE;
00727 if( 0 == mar_command( )) return( 0 );
00728 break;
00729
00730 case MDC_COM_DSET:
00731 mar_cmd = (int)task;
00732 wanted = (val+0.5*(1./cfg.dist_steps))*cfg.dist_steps;
00733 distance_steps = wanted;
00734
00735 mar_number = CMD_SET;
00736 mar_mode = ARG_WRITE;
00737 mar_par1 = 75;
00738 mar_par2 = wanted;
00739 stat_scanner_op = CMD_MOVE_DISTANCE;
00740 motor_op = stat_scanner_op;
00741
00742 emit print_message(QString().sprintf( "scan345: Defining DISTANCE as %1.3f\n",val));
00743 if( 0 == mar_command( )) return( 0 );
00744
00745 stat_dist = val;
00746 break;
00747
00748 case MDC_COM_PSET:
00749 mar_cmd = (int)task;
00750 delta = val;
00751 while(delta < 0.0)
00752 delta += 360.;
00753 while(delta >= 360.0)
00754 delta -= 360.;
00755 phi_steps = (delta+0.5 *(1./cfg.phi_steps))*cfg.phi_steps;
00756
00757 mar_number = CMD_SET;
00758 mar_mode = ARG_WRITE;
00759 mar_par1 = 80;
00760 mar_par2 = phi_steps;
00761
00762 stat_scanner_op = CMD_SET;
00763 motor_op = stat_scanner_op;
00764
00765 emit print_message(QString().sprintf( "scan345: Defining PHI as %1.3f\n",val));
00766 if( 0 == mar_command( )) return( 0 );
00767 stat_phi = delta;
00768
00769 break;
00770
00771 case MDC_COM_OSET:
00772 mar_cmd = (int)task;
00773 delta = val;
00774 while(delta < 0.0)
00775 delta += 360.;
00776 while(delta >= 360.0)
00777 delta -= 360.;
00778 omega_steps = (delta+0.5*(1./cfg.ome_steps))*cfg.ome_steps;
00779
00780 mar_number = CMD_SET;
00781 mar_mode = ARG_WRITE;
00782 mar_par1 = 76;
00783 mar_par2 = omega_steps;
00784 stat_scanner_op = CMD_MOVE_OMEGA;
00785 motor_op = stat_scanner_op;
00786
00787 emit print_message(QString().sprintf( "scan345: Defining OMEGA as %1.3f\n",val));
00788 if( 0 == mar_command( )) return( 0 );
00789 stat_omega = delta;
00790
00791 break;
00792
00793 case MDC_COM_DISTANCE:
00794 mar_cmd = (int)task;
00795
00796 if( ! cfg.use_dist ) {
00797 stat_dist = val;
00798 break;
00799 }
00800
00801 wanted = (val+0.5*(1./cfg.dist_steps))*cfg.dist_steps;
00802 target_steps = wanted;
00803 if(wanted < distance_steps) {
00804 #ifdef TRANS_BACK
00805
00806 wanted -= 100;
00807 mar_par4 = wanted + 100;
00808 mar_par5 = cfg.dist_speed;
00809 #else
00810 mar_par4 = wanted;
00811 #endif
00812 }
00813 else {
00814 mar_par4 = wanted;
00815 }
00816
00817 dist_retry = 0;
00818 original_distance = stat_dist;
00819 target_distance = val;
00820 stat_scanner_op = CMD_MOVE_DISTANCE;
00821 motor_op = stat_scanner_op;
00822 mar_number = CMD_MOVE;
00823 mar_mode = ARG_DISTANCE;
00824 mar_par1 = ARG_MOVE_ABS;
00825 mar_par2 = wanted;
00826 mar_par3 = cfg.dist_speed;
00827 mar_par5 = cfg.dist_speed;
00828
00829 emit print_message(QString().sprintf( "scan345: Moving DISTANCE from %1.3f to %1.3f\n",stat_dist,target_distance));
00830
00831 if( 0 == mar_command( )) return( 0 );
00832
00833 break;
00834
00835 case MDC_COM_PHI:
00836 mar_cmd = (int)task;
00837 delta = val;
00838 if(delta < 0.0 ) delta += 360.;
00839 if(delta > 360.0 ) delta -= 360.;
00840
00841 if( ! cfg.use_phi ) {
00842 stat_phi = delta;
00843 break;
00844 }
00845
00846
00847 wanted = (delta+0.5*(1./cfg.phi_steps))*cfg.phi_steps;
00848 nsteps_to_move = wanted - phi_steps;
00849 while ( abs(nsteps_to_move) > 180 * cfg.phi_steps) {
00850 if(nsteps_to_move < 0)
00851 nsteps_to_move += 360 * cfg.phi_steps;
00852 else
00853 nsteps_to_move = nsteps_to_move - 360 * cfg.phi_steps;
00854 }
00855
00856
00857 if ( nsteps_to_move < 0 ) {
00858 nsteps_to_move -= 125;
00859 mar_par4 = 125;
00860 mar_par5 = cfg.phi_speed/2;
00861 }
00862 else {
00863 mar_par4 = 0;
00864 mar_par5 = cfg.phi_speed;
00865 }
00866
00867 target_phi = delta;
00868 stat_scanner_op = CMD_MOVE_PHI;
00869 motor_op = stat_scanner_op;
00870 mar_number = CMD_MOVE;
00871 mar_mode = ARG_PHI;
00872 mar_par1 = ARG_MOVE_REL;
00873 mar_par2 = nsteps_to_move;
00874 mar_par3 = cfg.phi_speed;
00875
00876 emit print_message(QString().sprintf( "scan345: Moving PHI from %1.3f to %1.3f\n",stat_phi,target_phi));
00877 if( 0 == mar_command( )) return( 0 );
00878
00879 break;
00880
00881 case MDC_COM_OMOVE:
00882 mar_cmd = (int)task;
00883 target_omega = val;
00884 if( !cfg.use_ome ) {
00885 stat_omega = val;
00886 break;
00887 }
00888
00889 nsteps_to_move = val*cfg.ome_steps;
00890
00891 if(nsteps_to_move == omega_steps && cfg.use_zaxis == 0 ) {
00892 break;
00893 }
00894 else if(nsteps_to_move < omega_steps ) {
00895 nsteps_to_move -= 250;
00896 mar_par4 = 250;
00897 mar_par5 = cfg.ome_speed;
00898 }
00899 else {
00900 mar_par4 = 0;
00901 mar_par5 = 0;
00902 }
00903
00904 stat_scanner_op = CMD_MOVE_OMEGA;
00905 motor_op = stat_scanner_op;
00906 mar_number = CMD_MOVE;
00907 mar_mode = ARG_OMEGA;
00908 mar_par1 = ARG_MOVE_REL;
00909 mar_par2 = nsteps_to_move;
00910 mar_par3 = cfg.ome_speed;
00911
00912 emit print_message(QString().sprintf( "scan345: Moving OMEGA from %1.3f to %1.3f\n",stat_omega,target_omega));
00913 if( 0 == mar_command( )) return( 0 );
00914
00915 break;
00916
00917 case MDC_COM_ERASE:
00918 cur_mode = com_scanmode;
00919 mar_cmd = (int)task;
00920 erase_start = -1;
00921 erase_lamps_ok = 0;
00922 erase_time = cfg.erasetime[ stat_scanmode ];
00923
00924
00925 change_mode = 0;
00926 emit print_message("scan345: Erasing ...\n");
00927 i = mar_change_mode();
00928 break;
00929
00930 case MDC_COM_SCAN:
00931
00932 mar_cmd = (int)task;
00933
00934
00935 if ( input_keep_spiral || com_use_spiral )
00936 keep_spiral = 1;
00937 else
00938 keep_spiral = 0;
00939
00940
00941 if ( input_keep_image )
00942 keep_image = 1;
00943 else {
00944 keep_image = 0;
00945 keep_spiral = 1;
00946 }
00947
00948 stat_xray_units = 0.0;
00949 skip_op = 0;
00950 erase_start = -1;
00951
00952 stat_scan_add = 0;
00953 stat_scanner_op = CMD_SCAN;
00954 mar_number = CMD_SCAN;
00955 current_pixel = 0;
00956 cur_mode = com_scanmode;
00957 cur_pixelsize = cfg.pixelsize [cur_mode];
00958 cur_diameter = cfg.diameter [cur_mode];
00959 erase_lamps_ok = 0;
00960
00961 change_mode = 1;
00962 i = mar_change_mode();
00963 break;
00964
00965 case MDC_COM_COLL:
00966 mar_cmd = (int)task;
00967
00968
00969 time(&tick);
00970 strcpy( start_time, (char *)ctime(&tick) );
00971
00972
00973 expo_doseavg = expo_dosesig = 0.0;
00974 expo_dosemin = expo_dosebeg = 99999.0;
00975 expo_dosemax = expo_doseend = 0.0;
00976 expo_dosen = 0;
00977 memset( (char *)expo_dose, 0, sizeof(int)*MAX_DOSE );
00978
00979
00980 exposure_start = 0;
00981
00982
00983 stat_time = com_time;
00984 stat_phibeg = com_phibeg;
00985 stat_dphi = com_dphi;
00986 stat_n_passes = com_phiosc;
00987 stat_mode = com_mode;
00988 stat_scanner_op = CMD_MOVE;
00989 totpass = stat_n_passes;
00990 stat_phiend = stat_phibeg + stat_dphi;
00991 stat_start_phi = stat_phi;
00992
00993
00994 com_phi_steps = (int)( cfg.phi_steps * (stat_dphi * 100000. + 1 )/100000.);
00995
00996
00997 if(stat_mode == ARG_TIME ) {
00998 if ( com_phi_steps == 0 || cfg.use_phi == 0 )
00999 stat_units = (cfg.units_time * stat_time);
01000 else
01001 stat_units = (cfg.units_time * stat_time)/(com_phi_steps*stat_n_passes);
01002 }
01003
01004
01005 else {
01006 stat_units = stat_time;
01007 }
01008
01009
01010 if ( stat_units > 0 ) {
01011 if ( com_phibeg != stat_phi )
01012 i = mar_move_phi( -9999. );
01013 else
01014 i = mar_start_expo();
01015 }
01016
01017 break;
01018
01019 case MDC_COM_MODE:
01020 mar_cmd = (int)task;
01021 cur_mode = com_scanmode;
01022 stat_scanner_op = CMD_CHANGE;
01023 change_mode = 1;
01024 i = mar_change_mode();
01025 break;
01026
01027 default:
01028 return( 0 );
01029 }
01030
01031 #ifdef DEBUG
01032 if ( debug & 0x02 )
01033 emit print_message(QString().sprintf("debug (marhw:marTask): MAR %d, %d, %d, %d, %d, %d %d\n",
01034 mar_number,mar_mode,mar_par1,mar_par2,mar_par3,mar_par4,mar_par5));
01035 #endif
01036
01037 return( 1 );
01038 }
01039
01040
01041
01042
01043 int
01044 MarHW::get_status()
01045 {
01046 int i,status=0;
01047 static time_t before2=0;
01048 extern int status_interval;
01049
01050
01051
01052
01053
01054 now = time( NULL );
01055
01056 #ifdef SIMUL
01057 goto UPDATE;
01058 #endif
01059
01060
01061 if ( netcontrol==0 ) goto UPDATE;
01062
01063 i = net_data();
01064
01065
01066 while ( 1 ) {
01067 status = net_stat();
01068 if ( status < 200 ) break;
01069 }
01070
01071
01072 #ifdef DEBUG
01073 if ( debug & 0x04 )
01074 printf("debug (marhw:get_status) read=%d\n",status);
01075 #endif
01076
01077 i = net_msg ( );
01078
01079 UPDATE:
01080
01081 if ( (now-before2)> 1 ) {
01082
01083 before2 = time(NULL);
01084 }
01085
01086 if ( !scan_in_progress ) {
01087 sleep( 1 );
01088 }
01089
01090 return( status );
01091 }
01092
01093
01094
01095
01096
01097 int
01098 MarHW::process_status( char *buf )
01099 {
01100 int i,j,k;
01101 static int p_active [MAX_CMD];
01102 static int p_error [MAX_CMD];
01103 static int p_task [MAX_CMD] = {1234,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
01104 static char first_time = 1;
01105 static int p_gap = 999;
01106
01107
01108 static int idx[8] = { CMD_SCAN, CMD_COLLECT, CMD_MOVE,
01109 CMD_ERASE, CMD_SHUTTER, CMD_CHANGE,
01110 CMD_LOCK, CMD_ION_CHAMBER};
01111
01112
01113 memcpy( (char *)&esd_stb, buf, sizeof( ESD_STB ) );
01114
01115 if ( esd_stb.counter <= p_counter ) {
01116 sprintf( str, "scan345: ERROR at STATUS block # %d (last was %d)\n",
01117 esd_stb.counter,p_counter);
01118 emit print_message( str );
01119 p_counter = esd_stb.counter;
01120 return 0;
01121 }
01122
01123 p_counter = esd_stb.counter;
01124
01125 stat_pixels = esd_stb.valid_data;
01126 stat_scanmode = esd_stb.scanmode - 1;
01127
01128 if ( stat_scanmode < 0 || stat_scanmode > 7 ) {
01129 stat_scanmode = 0;
01130 }
01131
01132
01133 if ( p_task[0] == 1234 ) {
01134 for ( i=0; i<MAX_CMD; i++ ) p_task[i] = esd_stb.task[i];
01135 }
01136
01137
01138
01139
01140
01141 stat_xray_shutter = esd_stb.hw_status1 & two32[ 11 ];
01142 stat_reference_status = esd_stb.hw_status1 & two32[ 9 ];
01143
01144 stat_erase_T = esd_stb.hw_status1 & two32[ 21 ];
01145 stat_erase_R = esd_stb.hw_status1 & two32[ 20 ];
01146 stat_erase_L = esd_stb.hw_status1 & two32[ 19 ];
01147
01148 stat_erase_T_temp = esd_stb.hw_status1 & two32[ 31 ];
01149 stat_erase_R_temp = esd_stb.hw_status1 & two32[ 25 ];
01150 stat_erase_L_temp = esd_stb.hw_status1 & two32[ 24 ];
01151
01152 stat_servo_warning = esd_stb.hw_status1 & two32[ 23 ];
01153 stat_laser_status = esd_stb.hw_status1 & two32[ 22 ];
01154 stat_lock_permit = esd_stb.hw_status1 & two32[ 18 ];
01155
01156
01157 if ( (esd_stb.hw_status1 & two32[16]) == 0)
01158 stat_plate_locked = 1;
01159 else
01160 stat_plate_locked = 0;
01161
01162
01163 if ( esd_stb.task[CMD_RADIAL] & 0x01 )
01164 stat_home = 1;
01165 else
01166 stat_home = 0;
01167
01168 if ( esd_stb.task[CMD_SCAN] & 0x02 )
01169 stat_scan_active = 1;
01170 else
01171 stat_scan_active = 0;
01172
01173 distance_steps = esd_stb.stepper[0][STEPPER_IST];
01174 omega_steps = esd_stb.stepper[1][STEPPER_IST];
01175 phi_steps = esd_stb.stepper[5][STEPPER_IST];
01176
01177 for ( i=0; i<6; i++ ) {
01178 if ( esd_stb.stepper[i][STEPPER_IST] !=
01179 esd_stb.stepper[i][STEPPER_SOLL] )
01180 motor_moving[i] = 1;
01181 else
01182 motor_moving[i] = 0;
01183 }
01184
01185 stat_intensity = esd_stb.intensity / 1000.;
01186
01187 if ( cfg.use_phi ) {
01188 stat_phi = (float)((float)phi_steps /cfg.phi_steps);
01189 while( stat_phi < 0.0 ) {
01190 stat_phi += 360.;
01191 }
01192 while( stat_phi > 359.999 ) {
01193 stat_phi -= 360.;
01194 }
01195 }
01196 if ( cfg.use_dist && distance_steps > 0 )
01197 stat_dist = (float)((float)distance_steps/cfg.dist_steps);
01198 if ( cfg.use_ome )
01199 stat_omega = (float)((float) omega_steps /cfg.ome_steps);
01200
01201 erase_lamps_ok = 1;
01202
01203 if ( stat_xray_shutter )
01204 stat_xray_shutter = SHUTTER_IS_CLOSED;
01205 else
01206 stat_xray_shutter = SHUTTER_IS_OPEN;
01207
01208
01209 for ( k=0; k<8; k++ ) {
01210 i = idx[k];
01211
01212 task_done [i] = esd_stb.task[i] & two32[ 0 ];
01213 task_active [i] = esd_stb.task[i] & two32[ 1 ];
01214 task_queued [i] = esd_stb.task[i] & two32[ 4 ];
01215 task_started [i] = esd_stb.task[i] & two32[ 2 ];
01216 task_error [i] = esd_stb.task[i] & two32[ 8 ];
01217
01218
01219
01220
01221
01222 if ( !(esd_stb.task[i] & 0x10) ) {
01223
01224 if ( ( (esd_stb.task[i] & 0x02 ) || esd_stb.task[i] != p_task[i] ) && i != CMD_ABORT ) {
01225 stat_task_number = i;
01226 stat_task_active = task_active [i];
01227 stat_task_done = task_done [i];
01228 stat_task_error = task_error [i];
01229
01230 if ( stat_task_error ) {
01231 if ( first_time ) {
01232 stat_task_number = 0;
01233 goto SKIP1;
01234 continue;
01235
01236 }
01237 emit print_message(QString().sprintf("scan345: ERROR ending of task %d\n",i));
01238
01239 }
01240
01241 j = mar_progress( stat_task_number, stat_task_active, stat_task_error );
01242 }
01243 else
01244 stat_task_number = 0;
01245 }
01246 SKIP1:
01247 p_active[i] = task_active[i];
01248 p_error [i] = task_error[i];
01249 p_task [i] = esd_stb.task[i];
01250 }
01251
01252 first_time = 0;
01253
01254 #ifdef OLDGAPS
01255 if ( p_gap == 0 && esd_stb.gaps[0] != 0 ) {
01256 stat_gap = esd_stb.gaps[0];
01257 }
01258 p_gap = esd_stb.gaps[0];
01259 #endif
01260
01261
01262 for (i=0;i<8;i++) {
01263 if ( esd_stb.gaps[i] != 0 )
01264 stat_gap[i] = esd_stb.gaps[i];
01265 }
01266
01267 return 1;
01268 }
01269
01270
01271
01272
01273 int
01274 MarHW::mar_progress(int task, int active, int error)
01275 {
01276 char done=0;
01277 int fehler = 0;
01278 float ftmp;
01279 static int last_xray_shutter;
01280 static int ntry=0;
01281 static int pdone;
01282 static char p_move = 0;
01283 static char expo_first = 1;
01284
01285
01286
01287
01288 done = 0;
01289
01290
01291
01292
01293
01294
01295
01296
01297 switch( task ) {
01298
01299 case CMD_SHELL:
01300
01301 if ( active ) break;
01302
01303 done = 1;
01304
01305 if ( error ) {
01306 fehler = get_error( 0 );
01307 if ( fehler < 0 ) error = 0;
01308 }
01309 break;
01310
01311 case CMD_MOVE:
01312
01313
01314
01315
01316
01317
01318
01319 if ( active == 0 && p_move == 0 ) break;
01320 p_move = active;
01321
01322
01323 if( active ) {
01324 stat_scanner_msg = 0;
01325 if ( mar_mode == ARG_DISTANCE || mar_mode == ARG_THETA ) {
01326 if ( target_distance != original_distance )
01327 ftmp = 100 * (stat_dist-original_distance)/(original_distance - target_distance );
01328 else
01329 ftmp = 100.0;
01330
01331 stat_scanner_msg = (int)(ftmp+0.5);
01332 if ( stat_scanner_msg < 0 ) stat_scanner_msg *= -1;
01333 }
01334 else if ( mar_mode == ARG_PHI || mar_mode == ARG_CHI ) {
01335 i = esd_stb.stepper[mar_mode-1][STEPPER_SOLL] - esd_stb.stepper[mar_mode-1][STEPPER_IST];
01336 if ( mar_par2 != 0 )
01337 ftmp = 100. * i/ (float)mar_par2;
01338 stat_scanner_msg = 100-(int)(ftmp+0.5);
01339 if ( stat_scanner_msg < 0 ) stat_scanner_msg *= -1;
01340 }
01341 break;
01342 }
01343
01344
01345 if ( error ) {
01346 fehler = get_error( 0 );
01347 if ( fehler < 0 ) error = 0;
01348 }
01349
01350
01351 if ( mar_mode == ARG_DISTANCE ) {
01352 if( cfg.use_dist == 0 ) {
01353 done = 1;
01354 break;
01355 }
01356
01357
01358 if ( error ) {
01359
01360 stat_scanner_op = CMD_MOVE_DISTANCE;
01361
01362
01363 if ( fehler == 225 &&
01364 (distance_steps == (int)(cfg.dist_min *cfg.dist_steps) || distance_steps == (int)(cfg.dist_max *cfg.dist_steps) ) ) {
01365 marError(225, 0 );
01366 done = 1;
01367 mar_number = CMD_MOVE;
01368 mar_mode = ARG_DISTANCE;
01369 mar_par3 = cfg.dist_speed;
01370 mar_par1 = 2*(( cfg.dist_max - cfg.dist_min )*cfg.dist_steps/cfg.dist_speed);
01371 if ( distance_steps <= (int)(cfg.dist_min *cfg.dist_steps )) {
01372 if ( dist_retry < 2 ) {
01373 mar_par1 = ARG_INIT_NEAR;
01374 mar_par2 = cfg.dist_min*cfg.dist_steps;
01375 }
01376 else {
01377 mar_par1 = ARG_INIT_FAR;
01378 mar_par2 = cfg.dist_max*cfg.dist_steps;
01379 }
01380 }
01381 else {
01382 if ( dist_retry < 2 ) {
01383 mar_par1 = ARG_INIT_FAR;
01384 mar_par2 = cfg.dist_max*cfg.dist_steps;
01385 }
01386 else {
01387 mar_par1 = ARG_INIT_NEAR;
01388 mar_par2 = cfg.dist_min*cfg.dist_steps;
01389 }
01390 }
01391
01392 }
01393
01394
01395 else if ( fehler == 225 ) {
01396 marError( 225, 1);
01397 done = 1;
01398 break;
01399 }
01400
01401
01402 else if ( fehler == 217 ) {
01403 marError( 217, 0);
01404 done = 1;
01405 break;
01406 }
01407
01408 dist_retry++;
01409
01410 done = 1;
01411 if ( dist_retry < 4 ) {
01412 i = mar_command( );
01413 }
01414 else {
01415 done = 1;
01416 }
01417
01418 break;
01419 }
01420
01421
01422 else {
01423 dist_retry = 0;
01424 done = 1;
01425 break;
01426 }
01427 }
01428
01429
01430
01431 else if ( mar_mode == ARG_OMEGA ) {
01432
01433
01434 if( cfg.use_ome == 0 ) {
01435 done = 1;
01436 break;
01437 }
01438
01439 if ( active ) break;
01440
01441
01442 done = 1;
01443 break;
01444 }
01445
01446
01447 else if ( mar_mode == ARG_PHI ) {
01448
01449
01450 if( cfg.use_phi == 0 ) {
01451 done = 1;
01452 break;
01453 }
01454
01455
01456 if ( active ) break;
01457
01458
01459
01460 stat_start_phi = stat_phi;
01461
01462
01463 if ( mar_cmd == MDC_COM_COLL ) {
01464 done = 0;
01465 i=mar_start_expo( );
01466 }
01467 else {
01468 done = 1;
01469
01470 i = Modulo360();
01471 }
01472 }
01473
01474 break;
01475
01476 case CMD_ABORT:
01477 if ( active ) break;
01478 if ( active == 0 && p_task_active == 0 ) break;
01479
01480 if ( error ) {
01481 fehler = get_error(1);
01482 if ( fehler < 0 ) error = 0;
01483 }
01484
01485 if ( scan_in_progress ) {
01486 done=0;
01487 break;
01488 }
01489 else {
01490 marTask( MDC_COM_CHAMBER, 1.0 );
01491
01492
01493 i = Modulo360();
01494
01495 sleep( 1 );
01496 done = 1;
01497 }
01498 break;
01499
01500 case CMD_SHUTTER:
01501
01502
01503 if ( active ) break;
01504
01505
01506 if ( error ) {
01507
01508 fehler = get_error(0);
01509 if ( fehler < 0 )
01510 error = 0;
01511 else {
01512 #ifdef SKIP_RECOVER
01513 printf("scan345: Shutter error\n");
01514 done = 1;
01515 break;
01516 #endif
01517
01518 ntry =0;
01519 if ( fehler == 205 ) {
01520
01521 marError( 205, ntry );
01522 stat_scanner_op = CMD_SHUTTER;
01523 mar_number = CMD_SHUTTER;
01524 mar_mode = ARG_CLOSE;
01525 mar_par1 = mar_par2 = 0;
01526 mar_par3 = mar_par4 = mar_par5 = 0;
01527 if( 0 == mar_command( )) return( 0 );
01528 }
01529 else if ( fehler == 210 ) {
01530
01531 marError( 210, ntry );
01532 }
01533 }
01534 }
01535 else {
01536 if ( mar_cmd == MDC_COM_SHUT ) {
01537 done = 1;
01538 ntry = 0;
01539 }
01540 else
01541 done = 0;
01542 }
01543
01544
01545 if( mar_cmd == MDC_COM_INIT && cfg.use_dist ) {
01546 mar_number = CMD_MOVE;
01547 mar_mode = ARG_DISTANCE;
01548 if (target_distance == cfg.dist_max) {
01549 mar_par1 = ARG_INIT_FAR;
01550 mar_par2 = (cfg.dist_max + 0.5 * (1. / cfg.dist_steps)) * cfg.dist_steps;
01551 }
01552 else {
01553 mar_par1 = ARG_INIT_NEAR;
01554 mar_par2 = (cfg.dist_min + 0.5 * (1. / cfg.dist_steps)) * cfg.dist_steps;
01555 }
01556 mar_par3 = cfg.dist_speed;
01557 mar_par4 = 0;
01558 mar_par5 = cfg.dist_speed/10;
01559 if( 0 == mar_command( )) return( 0 );
01560
01561 done = 0;
01562 stat_scanner_op = CMD_MOVE_DISTANCE;
01563 motor_op = stat_scanner_op;
01564 }
01565
01566 break;
01567
01568 case CMD_ERASE:
01569
01570 if ( erase_start > 0 && erase_time > 0.00 )
01571 stat_scanner_msg = 100 * ( time(NULL) - erase_start)/erase_time;
01572 else
01573 stat_scanner_msg = 0;
01574
01575
01576 if ( active ) break;
01577
01578
01579
01580
01581
01582
01583
01584 if( error ) {
01585 fehler = get_error(1);
01586 if ( fehler < 0 )
01587 error = 0;
01588 else {
01589 done = 1;
01590 #ifdef SKIP_RECOVER
01591 printf("scan345: ERASE error\n");
01592 break;
01593 #endif
01594
01595 break;
01596 }
01597 }
01598
01599 pdone= 0;
01600 done = 1;
01601 break;
01602
01603 case CMD_LOCK:
01604
01605 if( active ) break;
01606
01607 if( error ) {
01608
01609 fehler = get_error(1);
01610 if ( fehler < 0 )
01611 error = 0;
01612 else {
01613 #ifdef SKIP_RECOVER
01614
01615 printf("scan345: LOCK error\n");
01616 done = 1;
01617 break;
01618 #endif
01619
01620 if ( fehler == 60 ) {
01621 done = 1;
01622 break;
01623 }
01624 }
01625 }
01626 if ( mar_cmd == MDC_COM_STARTUP ) {
01627 done = 1;
01628 }
01629 break;
01630
01631 case CMD_CHANGE:
01632 done = 0;
01633 if ( active ) break;
01634
01635
01636 if ( mar_cmd == MDC_COM_MODE || mar_cmd == MDC_COM_STARTUP ) {
01637
01638
01639 i = Modulo360();
01640
01641 done = 1;
01642 }
01643
01644 if ( error ) {
01645 fehler = get_error( 1 );
01646 if ( fehler < 0 )
01647 error = 0;
01648 else {
01649 done = 1;
01650 scan_in_progress = 0;
01651 break;
01652 }
01653 }
01654
01655
01656 if ( mar_cmd == MDC_COM_SCAN ) {
01657
01658 i = StartScan();
01659 done = 0;
01660 }
01661
01662 else if ( mar_cmd == MDC_COM_COLL ) {
01663 i = mar_erase();
01664 break;
01665 }
01666 break;
01667
01668 case CMD_COLLECT:
01669 if ( exposure_start == 0 && totpass == stat_n_passes ) {
01670 exposure_start = time(NULL);
01671 }
01672
01673
01674 if ( active ) {
01675
01676 if ( expo_first ) {
01677 xray_start = stat_intensity;
01678 expo_first = 0;
01679 }
01680
01681 done = 0;
01682
01683
01684
01685
01686
01687 if ( com_phi_steps < 1 || cfg.use_phi == 0 ) {
01688 if ( exposure_start > 0 )
01689 pdone = 100 * ( time(NULL) - exposure_start )/stat_time;
01690 else
01691 pdone = 0;
01692 }
01693
01694
01695
01696
01697 else {
01698 if ( stat_phi >= stat_start_phi )
01699 ftmp = stat_dphi * ( stat_n_passes - totpass ) + stat_phi - stat_start_phi;
01700 else
01701 ftmp = stat_dphi * ( stat_n_passes - totpass );
01702 pdone = 100 * ftmp / ( stat_dphi * stat_n_passes );
01703
01704 }
01705 stat_scanner_msg = pdone;
01706
01707 if ( stat_n_passes > 1 ) {
01708 stat_oscil_msg = stat_scanner_msg;
01709 }
01710
01711
01712
01713
01714
01715 if ( stat_intensity < cur_intensmin &&
01716 cfg.use_xray == 0 ) {
01717 if ( dc_stop == 0 )
01718 marError( 1060, 0 );
01719 dc_stop = 1;
01720 }
01721
01722
01723 if ( expo_dosen < MAX_DOSE )
01724 expo_dose[expo_dosen]= stat_intensity;
01725 expo_dosen++;
01726 expo_doseavg += stat_intensity;
01727 stat_xray_units += stat_intensity;
01728 expo_doseend = stat_intensity;
01729 if ( expo_dosebeg > 99990 )
01730 expo_dosebeg = stat_intensity;
01731 max0( expo_dosemax, stat_intensity);
01732 min0( expo_dosemin, stat_intensity);
01733 intensity_counter++;
01734 break;
01735 }
01736
01737 expo_first = 1;
01738
01739
01740 if ( error ) {
01741
01742 fehler = get_error( 0 );
01743
01744 if ( fehler < 0 )
01745 error = 0;
01746 else {
01747
01748
01749 if ( fehler == 238 ) {
01750 marError( fehler, 0);
01751 }
01752
01753 else if ( fehler == 215 || fehler == 241 ) {
01754 marError( fehler, 0);
01755 }
01756
01757 else if ( fehler == 234 ) {
01758 marError( fehler, 0);
01759 }
01760
01761 else if ( fehler == 239 ) {
01762 marError( fehler, 0);
01763 }
01764
01765 done = 1;
01766 break;
01767 }
01768 }
01769
01770
01771
01772
01773 totpass--;
01774
01775
01776 if ( totpass > 0 && cfg.use_phi ) {
01777
01778 if ( stop_image > 1 ) {
01779 done = 1;
01780 break;
01781 }
01782
01783 stat_scanner_op = CMD_MOVE_PHI;
01784 i = mar_move_phi( (double)-stat_dphi );
01785 done = 0;
01786 break;
01787 }
01788
01789 done = 1;
01790 break;
01791
01792 case CMD_SCAN:
01793
01794
01795
01796
01797 if ( active ) {
01798 if ( maximum_pixels > 0 && stat_pixels < maximum_pixels ) {
01799 pdone = (int)(100*stat_pixels/(float)maximum_pixels);
01800 }
01801 else if ( stat_pixels >= maximum_pixels && pdone > 50 )
01802 pdone = 100;
01803 else
01804 pdone = 0;
01805
01806 stat_scanner_msg = pdone;
01807 break;
01808 }
01809
01810
01811
01812 scan_started = 0;
01813
01814
01815 if ( error ) {
01816 fehler = get_error( 0 );
01817
01818 if ( fehler < 0 ) {
01819 error = 0;
01820 }
01821 else {
01822
01823
01824 marError( fehler, 0 );
01825 scan_in_progress= 0;
01826 done = 1;
01827 if ( mar_cmd == MDC_COM_SCAN ) break;
01828
01829 mar_number = CMD_ABORT;
01830 mar_mode = CMD_COLLECT;
01831 mar_par1 = mar_par2 = 0;
01832 if( 0 == mar_command( )) return( 0 );
01833 break;
01834 }
01835 }
01836
01837 done = 1;
01838 pdone = 0;
01839 stat_scanner_msg= 100;
01840
01841 break;
01842
01843 case CMD_SET:
01844 case CMD_ION_CHAMBER:
01845 done = 1;
01846 break;
01847
01848 default:
01849 marError( 999, task );
01850 done = 1;
01851 break;
01852 }
01853
01854
01855
01856
01857
01858 last_xray_shutter = stat_xray_shutter;
01859
01860 time( &now );
01861 if ( done ) {
01862 stat_scanner_msg = MAR_CONTROL_IDLE;
01863 stat_scanner_op = MAR_CONTROL_IDLE;
01864 stat_scanner_control = MAR_CONTROL_IDLE;
01865
01866 emit print_message(QString("scan345: Task %1 ENDED at %2\n").arg(cmdstr[ stat_task_number ]).arg((char *)ctime( &now )));
01867
01868 if ( stat_task_number == CMD_SCAN ) {
01869 emit scan_finished();
01870 } else if (stat_task_number == CMD_ERASE) {
01871 emit erase_finished();
01872 } else {
01873 emit task_finished();
01874 }
01875
01876 if ( verbose )
01877 emit print_message(QString("scan345: Task %1 ENDED at %2\n").arg(cmdstr[ stat_task_number ]).arg((char *)ctime( &now )));
01878 } else {
01879 stat_scanner_control = MAR_CONTROL_ACTIVE;
01880 if ( time(NULL) - last > 1 ) {
01881
01882
01883 emit print_message(QString("scan345: Task %1 %2 % complete\n").arg(cmdstr[ stat_task_number ]).arg(stat_scanner_msg));
01884
01885 if ( verbose > 1 )
01886 emit print_message(QString().sprintf("scan345: Task %s %3d %% complete\n",
01887 cmdstr[ stat_task_number ], stat_scanner_msg));
01888 last = time( NULL );
01889 }
01890 }
01891
01892
01893
01894
01895 if ( done && com_scan_add && task == CMD_SCAN ) {
01896 if ( stdout != NULL ) {
01897 emit print_message(QString().sprintf("scan345: %d more SCAN%s to add ...\n", com_scan_add, com_scan_add > 1 ? "S":""));
01898 fflush( stdout );
01899 }
01900 if ( verbose )
01901 emit print_message(QString().sprintf("scan345: %d more SCAN%s to add ...\n", com_scan_add, com_scan_add > 1 ? "S":""));
01902 com_scan_add--;
01903 mar_cmd = MDC_COM_SCAN;
01904 done = 0;
01905
01906 i = mar_erase();
01907 }
01908 if ( done && com_scan_erase && ( task == CMD_SCAN || task == CMD_ERASE ) ) {
01909 if ( stdout != NULL ) {
01910 emit print_message(QString().sprintf("scan345: %d more ERASE cycle%s to go ...\n",
01911 com_scan_erase, com_scan_erase > 1 ? "s":"" ));
01912 fflush( stdout );
01913 }
01914 if ( verbose )
01915 emit print_message(QString().sprintf("scan345: %d more ERASE cycle%s to go ...\n",
01916 com_scan_erase, com_scan_erase > 1 ? "s":"" ));
01917 com_scan_erase--;
01918 mar_cmd = MDC_COM_ERASE;
01919 done = 0;
01920
01921 i = mar_erase();
01922 }
01923
01924 return ( (int)done);
01925 }
01926
01927
01928
01929
01930 int
01931 MarHW::mar_lock()
01932 {
01933 int i;
01934
01935 if ( stat_plate_locked ) return 1;
01936
01937
01938 if ( stat_lock_permit != 0 ) {
01939 sprintf( str, "scan345: IP still spinning. Halting plate ...\n" );
01940
01941 emit print_message( str );
01942 sprintf ( mar_str, "servo_speed 0\r");
01943 if( 0 == mar_command( )) return( 0 );
01944 for ( i=0; i<2; i++ ) {
01945 sleep ( 1 );
01946 get_status();
01947 }
01948 }
01949
01950 if ( stat_lock_permit != 0 ) {
01951 sprintf( str, "scan345: IP still spinning. Cannot lock plate ...\n" );
01952 return 0;
01953 }
01954
01955 sprintf( str, "scan345: Locking plate...\n" );
01956
01957 emit print_message( str );
01958
01959 mar_number = CMD_LOCK;
01960 mar_mode = 1;
01961 mar_par1 = cfg.prelock_speed;
01962 mar_par2 = cfg.lock_speed;
01963 mar_par3 = 0;
01964 mar_par4 = 0;
01965 mar_par5 = 0;
01966 mar_str[0] = '\0';
01967 if( 0 == mar_command( )) return( 0 );
01968
01969 sleep( 1 );
01970
01971 return 1;
01972 }
01973
01974
01975
01976
01977 int
01978 MarHW::mar_servo()
01979 {
01980 int i;
01981 static int ntimes = 0;
01982
01983
01984 if ( esd_stb.servo_state != 0 && ntimes < 30 ) {
01985 ntimes++;
01986 if ( ntimes < 30 ) {
01987 sprintf( str, "scan345: Waiting for SERVO system ...\n");
01988 emit print_message( str);
01989 sleep( 1 );
01990 i=mar_servo();
01991 return 0;
01992 }
01993
01994 ntimes = 0;
01995
01996 marError( 1001, esd_stb.servo_state);
01997
01998
01999 for ( i=0; i<4; i++ ) {
02000 if ( net_close( i ) ) {
02001 sprintf( str, "scan345: socket %d closed ...\n",i+1);
02002 emit print_message( str );
02003 }
02004 }
02005 netcontrol = 0;
02006 return 0;
02007 }
02008
02009 sprintf( str, "scan345: SERVO system READY ...\n");
02010 emit print_message(str);
02011
02012
02013
02014
02015
02016
02017
02018 i=mar_lock();
02019
02020
02021 if ( esd_stb.scanmode > 0 && esd_stb.scanmode < 9 ) {
02022
02023
02024 i = Modulo360();
02025 return 1;
02026 }
02027
02028
02029 sprintf( str, "scan345: Initializing default scanmode ...\n" );
02030 emit print_message(str );
02031
02032 return 1;
02033 }
02034
02035
02036
02037
02038 void
02039 MarHW::mar_initial_status()
02040 {
02041 stat_scanmode = 0;
02042 stat_omega = 0.0;
02043 stat_phibeg = 0.0;
02044 stat_dphi = 1.0;
02045 stat_n_images = 1;
02046 stat_n_passes = 1;
02047 stat_time = 60;
02048 stat_scanner_op = MAR_CONTROL_IDLE;
02049 stat_scanner_msg = MAR_CONTROL_IDLE;
02050 stat_scanner_control = MAR_CONTROL_IDLE;
02051 stat_xray_shutter = SHUTTER_IS_CLOSED;
02052 stat_fname[0] = '\0';
02053 strcpy( stat_dir, working_dir );
02054 memset( (char *)stat_gap, 0, 8*sizeof(int) );
02055
02056 }
02057
02058
02059
02060
02061 void
02062 MarHW::marError( int err_no, int idata )
02063 {
02064 char s1[128],s2[128], s3[64], s4[128];
02065 char *cptr;
02066 char timestr[26];
02067 int nl=1;
02068 int status = 0;
02069
02070 time(&tick);
02071 cptr = (char *) ctime(&tick);
02072
02073
02074 strcpy( s1, "" );
02075 strcpy( timestr, "" );
02076
02077
02078 sprintf( s1, "scan345: Error no. %d",err_no );
02079 emit print_message(QString().sprintf( "%s\n", s1 ));
02080
02081
02082 strncpy( timestr, cptr, 24);
02083 timestr[24]='\0';
02084 timestr[3]='-';
02085 timestr[7]='-';
02086 sprintf( s1, "scan345: Current time is: %s", timestr );
02087 emit print_message(QString().sprintf( "%s\n", s1 ));
02088
02089
02090 if ( mar_cmd == MDC_COM_COLL ||
02091 mar_cmd == MDC_COM_SCAN ) {
02092 sprintf( s4, "%s", stat_fname );
02093 sprintf( s1, "scan345: Current image is: %s", s4 );
02094 emit print_message(QString().sprintf( "%s\n", s1 ));
02095 }
02096 else
02097 strcpy( s4, "" );
02098
02099
02100 strcpy( s1, "" );
02101 strcpy( s2, "" );
02102 strcpy( s3, "" );
02103
02104
02105 if ( err_no > 998 ) goto OTHER_ERRORS;
02106
02107
02108
02109
02110
02111 if ( err_no == 225 ) {
02112 if ( idata == 0 )
02113 sprintf(s1, "Cannot LEAVE distance reference position !!!");
02114 else
02115 sprintf(s1, "Distance reference position touched ...");
02116 }
02117 else {
02118 sprintf(s1, "%s", err_msg[fehler_index].msg);
02119 }
02120 nl = 1;
02121 status = 1;
02122
02123 goto END_ERRORS;
02124
02125
02126
02127
02128
02129 OTHER_ERRORS:
02130
02131 switch( err_no ) {
02132
02133
02134
02135
02136 case 1000:
02137 sprintf(s1,"Error sending command to mar controller.");
02138 sprintf(s2,"Command number: %d", idata );
02139 status = 1;
02140 nl = 2;
02141 break;
02142
02143 case 1001:
02144 sprintf(s1, "SERVO system cannot be INITIALIZED");
02145 sprintf(s2 ,"Giving up. NO more scanner CONTROL");
02146 sprintf(s3 ,"Please retry by switching off the scanner ...");
02147 status = 1;
02148 nl = 3;
02149 break;
02150
02151 case 1112:
02152 sprintf(s1 ,"Error writing image array");
02153 status = 1;
02154 break;
02155
02156 case 1115:
02157 sprintf(s1 ,"Cannot write image header");
02158 status = 1;
02159 break;
02160
02161 case 1050:
02162 sprintf(s1,"SHUTTER did not work properly.");
02163 sprintf(s2,"Abandoning data collection...");
02164 status = 1;
02165 nl = 2;
02166 break;
02167
02168 case 1070:
02169 sprintf(s1,"Could not recover from previous errors");
02170 sprintf(s2,"after 5 trials.");
02171 status = 1;
02172 nl = 2;
02173 break;
02174
02175 case 1020:
02176 sprintf(s1, "Not enough disk space left in %s!", stat_dir);
02177 sprintf(s2, "Aborting data collection ...");
02178 status = 1;
02179 nl = 2;
02180 break;
02181
02182
02183
02184
02185
02186 case 1080:
02187 if (idata==0)
02188 sprintf(s1,"Shutter did not open during exposure");
02189 else
02190 sprintf(s1,"Shutter did not close at end of exposure");
02191 sprintf(s2, "Trying to fix shutter by doing 5 x open/close");
02192 nl = 2;
02193 status = 0;
02194 break;
02195
02196 case 1120:
02197 sprintf(s1 ,"Cannot open spiral file %s",spiral_file);
02198 status = 0;
02199 break;
02200
02201 case 1121:
02202 sprintf(s1 ,"Cannot write spiral header");
02203 status = 0;
02204 break;
02205
02206
02207
02208
02209 case 1030:
02210 sprintf(s1, "The Image Plate has been exposed to X-rays!");
02211 sprintf(s2, "Please, ERASE plate before next exposure...");
02212 status = 2;
02213 nl = 2;
02214 break;
02215
02216 case 1010:
02217 sprintf(s1, "Waiting for X-rays...");
02218 status = 2;
02219 nl = 1;
02220 break;
02221
02222 case 1060:
02223 sprintf(s1 ,"X-ray reading too low (%1.2f). ", stat_intensity);
02224 sprintf(s2 ,"Check generator or beam shutter!!!");
02225 sprintf(s3 ,"Data collection will end after current image...");
02226 status = 2;
02227 nl = 3;
02228 break;
02229
02230 case 1100:
02231 sprintf(s1, "Cannot open nb_code!");
02232 status = 1;
02233 nl = 1;
02234 break;
02235
02236 case 1101:
02237 sprintf(s1, "No scan modes found in nb_cde...");
02238 status = 1;
02239 nl = 1;
02240 break;
02241
02242 case 1102:
02243 sprintf(s1, "Something wrong with byteorder in nb_code");
02244 status = 1;
02245 nl = 1;
02246 break;
02247
02248 case 1103:
02249 sprintf(s1, "Scanner serial number in nb_code differs from config");
02250 status = 2;
02251 nl = 1;
02252 break;
02253
02254 case 1105:
02255 sprintf(s1, "No suitable scanning mode found in nb_code");
02256 status = 1;
02257 nl = 1;
02258 break;
02259
02260 case 1110:
02261 sprintf(s1 ,"Cannot create image file %s",image_file);
02262 status = 2;
02263 break;
02264
02265 case 1111:
02266 sprintf(s1 ,"Cannot open image file %s",image_file);
02267 status = 2;
02268 break;
02269
02270
02271
02272 case 999:
02273 sprintf(s1 ,"Task %d NOT implemented !!!",idata);
02274 break;
02275 default:
02276 break;
02277 }
02278
02279 END_ERRORS:
02280
02281
02282 emit print_message(QString().sprintf( "scan345: %s\n", s1 ));
02283
02284 if (nl>1) {
02285 emit print_message(QString().sprintf( " %s\n", s2 ));
02286 }
02287 if (nl>2) {
02288 emit print_message(QString().sprintf( " %s\n", s3 ));
02289 }
02290
02291 mar_error = err_no;
02292 }
02293
02294
02295
02296
02297 int
02298 MarHW::StartScan()
02299 {
02300 int i;
02301
02302
02303 if ( NotEnoughDiskSpace() ) {
02304 return 0;
02305 }
02306
02307 if ( intensity_counter > 0 )
02308 sum_xray_units = stat_xray_units/intensity_counter;
02309
02310
02311 if ( com_scan_add == 0 ) {
02312 stat_xray_units = 0.0;
02313 intensity_counter = 0;
02314
02315 if ( expo_dosen > 0 ) {
02316 expo_doseavg /= expo_dosen;
02317
02318 expo_dosesig = 0.0;
02319
02320 for ( i=0; i<expo_dosen; i++ ) {
02321 ftmp = expo_dose[i]/1000. - expo_doseavg;
02322 expo_dosesig += ( ftmp*ftmp );
02323 }
02324 expo_dosesig = sqrt( expo_dosesig / expo_dosen );
02325 }
02326
02327
02328 if ( stat_intensity > 0.0 && xray_start > -999. && cfg.use_xray == 0) {
02329 ftmp = xray_start/stat_intensity;
02330
02331
02332 if ( stat_mode == ARG_TIME )
02333 exposure_time = (int)stat_time;
02334 else {
02335 exposure_time = time(NULL)-exposure_start;
02336 }
02337 }
02338 }
02339
02340 memset( (char *)stat_gap, 0, sizeof(int)*8);
02341
02342 totpass = stat_n_passes;
02343 stat_phiend = stat_phi;
02344 stat_start_phi = stat_phi;
02345 scan_error = 0;
02346 current_pixel = 0;
02347 stat_scanner_msg= 100;
02348 stat_scanner_msg= 0;
02349 exposure_start = 0;
02350
02351
02352
02353 if ( stat_dir[ strlen(com_dir) - 1] != '/' )
02354 strcat( com_dir, "/" );
02355
02356 sprintf(str,"%s%s",com_dir,com_root);
02357
02358
02359 if ( com_scan_add || stat_scan_add ) {
02360 sprintf(spiral_file,"%s.%c.s" , str, (char)(stat_scan_add+97));
02361 }
02362 else
02363 sprintf(spiral_file,"%s.s" , str);
02364
02365 if ( com_format == OUT_MAR )
02366 sprintf(image_file, "%s.mar", str );
02367 else if ( com_format == OUT_CBF )
02368 sprintf(image_file, "%s.cbf", str );
02369 else if ( com_format == OUT_CIF )
02370 sprintf(image_file, "%s.cif", str );
02371 else if ( com_format == OUT_PCK )
02372 sprintf(image_file, "%s.pck", str );
02373 else if ( com_format == OUT_IMAGE )
02374 sprintf(image_file, "%s.image", str );
02375
02376 sprintf( str, "%1.0f", (float)(cur_diameter/cur_pixelsize));
02377 if ( com_format == OUT_MAR || com_format == OUT_CIF || com_format == OUT_CBF )
02378 strcat( image_file, str );
02379 strcat(spiral_file, str );
02380
02381 if ( expo_dosen < 1 ) {
02382 sum_xray_units = stat_intensity;
02383 expo_doseavg = stat_intensity;
02384 expo_dosemin = expo_doseavg;
02385 expo_dosemax = expo_doseavg;
02386 expo_dosesig = 0.0;
02387 expo_dosen = 1;
02388 }
02389
02390 erase_lamps_ok = 0;
02391 stat_scanner_msg= 0;
02392 scan_started = 1;
02393
02394
02395 com_scanmode = stat_scanmode;
02396 stat_scanner_op = CMD_SCAN;
02397 mar_number = CMD_SCAN;
02398 mar_mode = cfg.roff[ stat_scanmode ];
02399 mar_par1 = (int)cfg.flags;
02400 mar_par2 = (int)cfg.adcoff[ stat_scanmode ];
02401 mar_par3 = 0;
02402
02403 i = mar_command( );
02404
02405
02406 if ( mar_start_scan_readout(stat_scan_add) == 0 ) {
02407 printf("scan345: ERROR: SCAN could not be started\n");
02408 marTask( MDC_COM_ABORT, 0.0 );
02409 }
02410
02411 op_doseavg = expo_doseavg;
02412 op_dosemin = expo_dosemin;
02413 op_dosemax = expo_dosemax;
02414 op_dosesig = expo_dosesig;
02415 op_dosebeg = expo_dosebeg;
02416 op_doseend = expo_doseend;
02417 op_dosen = expo_dosen;
02418
02419 stat_scan_add++;
02420
02421
02422 if ( com_scan_add == 0 ) {
02423 expo_doseavg = expo_dosesig = 0.0;
02424 expo_dosemin = expo_dosebeg = 99999.0;
02425 expo_dosemax = expo_doseend = 0.0;
02426 expo_dosen = 0;
02427 memset( (char *)expo_dose, 0, sizeof(int)*MAX_DOSE );
02428 }
02429
02430 ict1 = ict2 = 0;
02431
02432 return i;
02433 }
02434
02435
02436
02437
02438 int
02439 MarHW::Modulo360()
02440 {
02441 int i;
02442 int steps;
02443 float ftmp, real_phi;
02444
02445 real_phi = (float)((float)esd_stb.stepper[5][STEPPER_IST]/ cfg.phi_steps);
02446
02447
02448 if ( real_phi < 0.0 || real_phi >= 360.0 ) {
02449 ftmp = real_phi;
02450 while( ftmp < 0.0)
02451 ftmp += 360.;
02452 while( ftmp >= 360.0)
02453 ftmp -= 360.;
02454
02455 sprintf(str, "scan345: Adjusting PHI (%1.3f -> %1.3f)\n",real_phi,ftmp);
02456 emit print_message( str );
02457
02458 steps = (ftmp+0.5 *(1./cfg.phi_steps))*cfg.phi_steps;
02459
02460 mar_number = CMD_SET;
02461 mar_mode = ARG_WRITE;
02462 mar_par1 = 80;
02463 mar_par2 = steps;
02464 i = mar_command( );
02465
02466 stat_phi = ftmp;
02467
02468
02469 i = 0;
02470 sleep(1);
02471 return 1;
02472 }
02473
02474 return 0;
02475 }
02476
02477
02478
02479
02480 void MarHW::print_msg(char *s)
02481 {
02482 int i,j,ival,jval;
02483 char b[8],op[128];
02484 char *sp;
02485 static char erledigt[4] = { 0, 0, 0, 0 };
02486
02487
02488
02489
02490
02491 op[0] = '\0';
02492
02493 sp = strstr( s, "MESS" );
02494 if ( sp == NULL )
02495 strcpy( op, s );
02496 else {
02497 j = strlen( s ) - strlen( sp );
02498
02499 if ( j > 0 ) {
02500 strcpy( op, s);
02501 op[ j ] = '\n';
02502 op[ j+1 ] = '\0';
02503 emit spy_message(op);
02504 }
02505
02506 strcpy( op, sp+4);
02507 }
02508
02509
02510 j = strlen( op )-1;
02511 for ( i=j; i>0; i-- ) {
02512 if ( op[i] != '\n' && op[i] != ' ' ) break;
02513 op[i] = '\0';
02514 }
02515 op[i+1] = '\n';
02516 op[i+2] = '\0';
02517
02518 emit spy_message(op);
02519
02520
02521 if ( ( sp = strstr( op, "SETPARAM" ) ) == NULL ) return;
02522 if ( strlen( sp ) < 44 ) return;
02523
02524 sscanf( sp+17, "%d", &ival );
02525 sscanf( sp+34, "%d", &jval );
02526
02527 op[0] = '\0';
02528 if ( ival == 95 && !erledigt[0]) {
02529 sprintf( op, "scan345: ESD Controller no.\t\t%d\n",jval);
02530 erledigt[0] = 1;
02531 }
02532 else if ( ival == 97 && !erledigt[1]) {
02533 sprintf( op, "scan345: ESD Firmware version\t\t%d\n",jval);
02534 erledigt[1] = 1;
02535 }
02536 else if ( ival == 278 && !erledigt[2]) {
02537 sprintf( op, "scan345: ESD RT-OS version\t\t%d\n",jval);
02538 erledigt[2] = 1;
02539 }
02540 else if ( ival == 279 && !erledigt[3]) {
02541 memcpy( b, (char *)&jval, 4);
02542 #if ( __linux__ || __osf__ )
02543 swaplong( b, 4 );
02544 #endif
02545 b[4] = '\0';
02546 sprintf( op, "scan345: ESD Servo version\t\t%s\n",b);
02547 erledigt[3] = 1;
02548 }
02549 if ( strlen( op ) ) {
02550 emit print_message(op);
02551 }
02552 }
02553
02554
02555
02556
02557 int
02558 MarHW::get_error(int mode)
02559 {
02560 int j,i,k,e;
02561 int result=0;
02562 STB_MSG msg;
02563
02564 fehler_index = 0;
02565
02566 for ( i=0; i<10; i++ ) {
02567 if ( esd_stb.errors[i] == 0 ) break;
02568
02569 e = esd_stb.errors[i];
02570 memcpy ( (char *)&msg, (char *)&e, 4 );
02571 if ( msg.mclass == 3 ) continue;
02572
02573 j = 1;
02574 while ( err_msg[j].task < 99 ) {
02575 if ( msg.number == err_msg[j].number ) break;
02576 j++;
02577 }
02578 if ( err_msg[j].task == 99 ) {
02579 sprintf( str, "scan345: ERROR %4d %4d %4d\n",
02580 msg.task,msg.mclass,msg.number );
02581 emit print_message(str);
02582 }
02583 else {
02584 fehler_index = j;
02585 sprintf( str, "scan345: ERROR %4d %4d %4d: %s\n",
02586 msg.task,msg.mclass,msg.number,err_msg[j].msg );
02587 emit print_message(str);
02588 }
02589
02590
02591 if ( cfg.use_error[0] > 0 ) {
02592 for ( k=1; k<cfg.use_error[0]; k++ ) {
02593 if ( msg.number == cfg.use_error[k] ) {
02594 sprintf( str, "scan345: Ignoring error # %d ...\n",msg.number);
02595 emit print_message(str);
02596 result = -1;
02597 break;
02598 }
02599 }
02600 }
02601
02602 if ( result != -1 ) {
02603 if ( msg.mclass == 1 )
02604 result = msg.number;
02605 if ( result == 0 && msg.mclass == 3 )
02606 result = msg.number;
02607 }
02608 }
02609
02610 if ( result > 0 && mode ) {
02611 marError( result, 0 );
02612 }
02613
02614 return result;
02615 }
02616
02617
02618
02619
02620 int
02621 MarHW::mar_start_expo()
02622 {
02623 time( &now );
02624
02625
02626 if ( esd_stb.task[CMD_COLLECT] & 0x02 ) {
02627 emit print_message("scan345: Exposure is still active. Igoring command ...\n");
02628 return 1;
02629 }
02630
02631
02632 if ( esd_stb.task[CMD_COLLECT] & 0x10 ) {
02633 emit print_message("scan345: Exposure is already queued. Igoring command ...\n");
02634 return 1;
02635 }
02636
02637
02638 mar_cmd = MDC_COM_COLL;
02639
02640
02641 mar_number = CMD_COLLECT;
02642 mar_mode = com_mode;
02643 mar_par1 = com_phi_steps;
02644 mar_par2 = stat_units;
02645 mar_par3 = cfg.shutter_delay;
02646 if ( mar_mode == ARG_DOSE ) mar_par3 = 0;
02647 mar_par4 = 0;
02648 mar_par5 = 0;
02649 mar_str[0] = '\0';
02650 if ( cfg.use_phi == 0 )
02651 mar_par2 = 1;
02652
02653 open_shutter_counter = 0;
02654 close_shutter_counter = 0;
02655 erase_start = -1;
02656 stat_xray_units = 0.0;
02657
02658 if ( totpass == stat_n_passes ) {
02659
02660 exposure_time = (int)stat_time;
02661 if ( stat_mode == ARG_TIME )
02662 emit print_message(QString().sprintf( "scan345: EXPOSE: %d * PHI = %1.3f -> %1.3f @ %1.0f sec.\n",
02663 com_phiosc,stat_phi,stat_phi+com_dphi,com_time));
02664 else
02665 emit print_message(QString().sprintf( "scan345: EXPOSE: %d * PHI = %1.3f -> %1.3f @ %1.0f counts\n",
02666 com_phiosc,stat_phi,stat_phi+com_dphi,stat_units));
02667 if ( stat_n_passes > 1 )
02668 emit print_message(QString().sprintf( "scan345: 1. oscillation\n"));
02669 }
02670 else
02671 emit print_message(QString().sprintf( "scan345: %2d. oscillation\n",stat_n_passes - totpass+1));
02672
02673 stat_scanner_op = CMD_COLLECT;
02674
02675
02676 if ( stat_units > 0 ) {
02677 if( 0 == mar_command( )) return( -1 );
02678 }
02679
02680 return(1);
02681 }