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 <string.h>
00023 #include <ctype.h>
00024 #include <math.h>
00025 #include <stdlib.h>
00026 #include <unistd.h>
00027
00028
00029
00030
00031 #include "marcmd.h"
00032 #include "config.h"
00033 #include "marglobals.h"
00034 #include "esd.h"
00035
00036 #include "command.h"
00037
00038 #define TOUPPER(a) for (j=strlen(a), i=0;i<j;i++ ) a[i] = toupper( a[i] )
00039 #define TOLOWER(a) for (j=strlen(a), i=0;i<j;i++ ) a[i] = tolower( a[i] )
00040
00041
00042
00043
00044 extern char scan_in_progress;
00045
00046
00047
00048 static float dfree,disk;
00049
00050
00051
00052
00053
00054 extern "C" {
00055 float GetDiskSpace(char*);
00056 void RemoveBlanks(char*);
00057 }
00058
00059 static int first=1;
00060
00061 Command::Command(QObject *parent)
00062 : inherited(parent)
00063 {
00064 }
00065
00066
00067
00068
00069 void
00070 Command::exec_command(const char *b)
00071 {
00072 static int frm=1;
00073 FILE *fp;
00074 int i,j, k, command=0, ntok;
00075 char s1[64], s2[64], s3[64], s4[64],s5[64],s6[64],s7[64],s8[32],key[8];
00076 char coll_phi=0,coll_time=0;
00077 float val=1.0;
00078 extern int stat_task_active;
00079 char buf[256];
00080
00081 if ( stat_task_active || scan_in_progress) return;
00082
00083 memset(buf, 0, sizeof(buf));
00084 strncpy(buf, b, sizeof(buf)-1);
00085
00086 if (strlen(buf)==0) return;
00087
00088
00089
00090 if (first) {
00091 mar_init_params();
00092 first = 0;
00093 }
00094
00095
00096 if( buf[0] == '#' || buf[0]=='!') return;
00097
00098
00099 key[0] = '\0';
00100 for (k=0, j=0, i=0; i<strlen( buf ); i++ ) {
00101 if ( isspace( buf[i] ) && j==0 ) continue;
00102 if ( isspace( buf[i] ) && j==1 ) break;
00103 j = 1;
00104 key[k] = toupper( buf[i] );
00105 k++;
00106 if (k>3) break;
00107 }
00108 key[4]='\0';
00109
00110
00111 for(i=0;i<strlen(buf);i++)if(buf[i]=='\n')buf[i]='\0';
00112
00113
00114 s1[0] = s2[0] = s3[0] = s4[0] = s5[0] = s6[0] = s7[0] = s8[0] = '\0';
00115 ntok = sscanf( buf , "%s%s%s%s%s%s%s%s", s1, s2, s3, s4, s5, s6, s7, s8);
00116
00117
00118 if(strstr(key,"DIR"))
00119 strcpy( com_dir, s2 );
00120
00121
00122 else if(strstr(key,"ROOT"))
00123 strcpy( com_root, s2 );
00124
00125
00126 else if(strstr(key,"PHI")) {
00127 if ( BadInput( 2, s2 ) )
00128 com_phibeg = 0.0;
00129 else
00130 com_phibeg = atof( s2 );
00131 if ( BadInput( 2, s3 ) )
00132 com_phiend = 0.0;
00133 else
00134 com_phiend = atof( s3 );
00135 if ( ntok > 3 ) {
00136 if ( BadInput( 1, s4 ) )
00137 com_phiosc = 1;
00138 else
00139 com_phiosc = atoi( s4 );
00140 }
00141 while ( com_phibeg < 0.0) com_phibeg += 360.0;
00142 while ( com_phibeg >=360.0) com_phibeg -= 360.0;
00143 while ( com_phiend < 0.0) com_phiend += 360.0;
00144 while ( com_phiend >=360.0) com_phiend -= 360.0;
00145 if ( com_phiend < com_phibeg )
00146 com_dphi = com_phiend + 360.0 - com_phibeg;
00147 else
00148 com_dphi = com_phiend - com_phibeg;
00149
00150 coll_phi = 1;
00151 }
00152
00153
00154 else if(strstr(key,"OMEG")) {
00155 if ( BadInput( 2, s2 ) )
00156 com_omebeg = 0.0;
00157 else
00158 com_omebeg = atof( s2 );
00159 if ( BadInput( 2, s3 ) )
00160 com_omeend = 0.0;
00161 else
00162 com_omeend = atof( s3 );
00163 if ( ntok > 3 ) {
00164 if ( BadInput( 1, s4 ) )
00165 com_omeosc = 0;
00166 else
00167 com_omeosc = atoi( s4 );
00168 }
00169 while ( com_omebeg < 0.0) com_omebeg += 360.0;
00170 while ( com_omebeg >=360.0) com_omebeg -= 360.0;
00171 while ( com_omeend < 0.0) com_omeend += 360.0;
00172 while ( com_omeend >=360.0) com_omeend -= 360.0;
00173
00174 com_dome = com_omeend - com_omebeg;
00175 }
00176
00177
00178 else if(strstr(key,"COLL")) {
00179 TOUPPER( s2 );
00180 if ( strstr( s2, "DOSE" ) )
00181 com_mode = ARG_DOSE;
00182 else
00183 com_mode = ARG_TIME;
00184
00185 if ( ntok > 2 ) {
00186 if ( !BadInput( 2, s3 ) ) {
00187 com_time = atof( s3 );
00188 coll_time = 1;
00189 }
00190 }
00191 }
00192
00193
00194 else if(strstr(key,"FORM")) {
00195 TOUPPER( s2 );
00196 if ( strstr( s2, "IMAGE" ) )
00197 com_format = OUT_IMAGE;
00198 else if ( strstr( s2, "SPIRAL" ) )
00199 com_format = OUT_SPIRAL;
00200 else if ( strstr( s2, "CBF" ) )
00201 com_format = OUT_CBF;
00202 else if ( strstr( s2, "CIF" ) )
00203 com_format = OUT_CIF;
00204 else
00205 com_format = OUT_MAR;
00206 }
00207
00208
00209 else if(strstr(key,"OSCI") ) {
00210 if ( BadInput( 1, s2 ) )
00211 com_phiosc = 1;
00212 else
00213 com_phiosc = atoi( s2 );
00214 }
00215
00216
00217 else if(strstr(key,"MODE") ) {
00218 if ( BadInput( 1, s2 ) )
00219 com_scanmode = 0;
00220 else {
00221 com_scanmode = atoi( s2 );
00222 if ( com_scanmode == 2300 )
00223 com_scanmode = 0;
00224 else if ( com_scanmode == 2000 )
00225 com_scanmode = 1;
00226 else if ( com_scanmode == 1600 )
00227 com_scanmode = 2;
00228 else if ( com_scanmode == 1200 )
00229 com_scanmode = 3;
00230 else if ( com_scanmode == 3450 )
00231 com_scanmode = 4;
00232 else if ( com_scanmode == 3000 )
00233 com_scanmode = 5;
00234 else if ( com_scanmode == 2400 )
00235 com_scanmode = 6;
00236 else if ( com_scanmode == 1800 )
00237 com_scanmode = 7;
00238 if ( com_scanmode < 0 || com_scanmode > 7 )
00239 com_scanmode = 0;
00240 }
00241
00242 com_diam = cfg.diameter [com_scanmode];
00243 com_pixelsize= cfg.pixelsize[com_scanmode];
00244 com_size = cfg.size [com_scanmode];
00245 }
00246
00247
00248 else if(strstr(key,"COMM") && command != MDC_COM_IPS ) {
00249 TOUPPER( s2 );
00250 command = MDC_COM_IDLE;
00251 if ( strstr( s2, "SCAN" ) ) {
00252 command = MDC_COM_SCAN;
00253
00254
00255 if ( ntok > 3 ) {
00256 TOUPPER( s3 );
00257 if ( strstr( s3, "ERAS" ) || strstr( s3, "CLEAN" ) ) {
00258 if ( !BadInput( 1, s4 ) ) {
00259 com_scan_erase = atoi( s4 );
00260 }
00261 }
00262 else if ( strstr( s3, "ADD" ) ) {
00263 if ( !BadInput( 1, s4 ) ) {
00264 com_scan_add = atoi( s4 );
00265 }
00266 }
00267 }
00268 if ( ntok > 5 ) {
00269 TOUPPER( s5 );
00270 if ( strstr( s5, "ADD" ) ) {
00271 if ( !BadInput( 1, s6 ) ) {
00272 com_scan_add = atoi( s6 );
00273 }
00274 }
00275 else if ( strstr( s5, "ERAS" ) || strstr( s5, "CLEAN" ) ) {
00276 if ( !BadInput( 1, s6 ) ) {
00277 com_scan_erase = atoi( s6 );
00278 }
00279 }
00280 }
00281 }
00282 else if ( strstr( s2, "ERAS" ) )
00283 command = MDC_COM_ERASE;
00284 else if ( strstr( s2, "STAR" ) )
00285 command = MDC_COM_STARTUP;
00286 else if ( strstr( s2, "STOP" ) || strstr( s2, "ABOR" ))
00287 command = MDC_COM_ABORT;
00288 else if ( strstr( s2, "CHAN" ) )
00289 command = MDC_COM_MODE;
00290 else if ( strstr( s2, "QUIT" ) )
00291 command = MDC_COM_QUIT;
00292 else if ( strstr( s2, "TEST" ) )
00293 command = -1;
00294 else if ( strstr( s2, "SHUT" ) ) {
00295 TOUPPER( s3 );
00296 if ( ntok < 3 ) {
00297 emit print_message("scan345: COMMAND SHUTTER must be followed by 'OPEN' or 'CLOSE' ...\n");
00298 return;
00299 }
00300 if ( strstr( s3, "OP" ) )
00301 val = 1.0;
00302 if ( strstr( s3, "CL" ) )
00303 val = 0.0;
00304 command = MDC_COM_SHUT;
00305 }
00306 else if ( strstr( s2, "INIT" ) ) {
00307 TOUPPER( s3 );
00308
00309 val = cfg.dist_max;
00310 if ( strstr( s3, "MIN" ) )
00311 val = cfg.dist_min;
00312 command = MDC_COM_INIT;
00313 }
00314 else if ( strstr( s2, "EXPO" ) ) {
00315
00316
00317 if ( ntok > 2 ) {
00318 if ( !BadInput( 2, s3 ) ) {
00319 com_dphi = atof( s3 );
00320 com_phibeg = stat_phi;
00321 com_phiend = com_phibeg + com_dphi;
00322 coll_phi = 1;
00323 }
00324 }
00325 if ( ntok > 3 ) {
00326 if ( !BadInput( 2, s4 ) ) {
00327 com_time = atof( s4 );
00328 coll_time = 1;
00329 }
00330 }
00331 if ( ntok > 4 ) {
00332 if ( !BadInput( 1, s5 ) ) {
00333 com_phiosc = atoi( s5 );
00334 }
00335 }
00336 command = MDC_COM_COLL;
00337 }
00338 else if ( strstr( s2, "PHI" ) ) {
00339 if ( ntok < 4 ) {
00340 emit print_message("scan345: COMMAND PHI must be followed by 'DEFINE' or 'MOVE' phi ...\n");
00341 return;
00342 }
00343 TOUPPER( s3 );
00344 if ( strstr( s3, "DEF" ) )
00345 command = MDC_COM_PSET;
00346 else if ( strstr( s3, "MOV" ) )
00347 command = MDC_COM_PHI;
00348 else {
00349 emit print_message("scan345: COMMAND PHI must be followed by 'DEFINE' or 'MOVE' phi ...\n");
00350 return;
00351 }
00352 if ( BadInput( 2, s4 ) )
00353 command = MDC_COM_IDLE;
00354 else
00355 val = (double)atof( s4 );
00356 }
00357 else if ( strstr( s2, "DIST" ) ) {
00358 if ( ntok < 4 ) {
00359 emit print_message("scan345: COMMAND DISTANCE must be followed by 'DEFINE' or 'MOVE' distance ...\n");
00360 return;
00361 }
00362 TOUPPER( s3 );
00363 if ( strstr( s3, "DEF" ) )
00364 command = MDC_COM_DSET;
00365 else if ( strstr( s3, "MOV" ) )
00366 command = MDC_COM_DISTANCE;
00367 else {
00368 emit print_message("scan345: COMMAND DISTANCE must be followed by 'DEFINE' or 'MOVE' distance ...\n");
00369 return;
00370 }
00371 if ( BadInput( 2, s4 ) )
00372 command = MDC_COM_IDLE;
00373 else
00374 val = (double)atof( s4 );
00375 }
00376 else if ( strstr( s2, "OMEG" ) ) {
00377 if ( ntok < 4 ) {
00378 emit print_message("scan345: COMMAND OMEGA must be followed by 'DEFINE' or 'MOVE' omega ...\n");
00379 return;
00380 }
00381 TOUPPER( s3 );
00382 if ( strstr( s3, "DEF" ) )
00383 command = MDC_COM_OSET;
00384 else if ( strstr( s3, "MOV" ) )
00385 command = MDC_COM_OMOVE;
00386 else {
00387 emit print_message("scan345: COMMAND OMEGA must be followed by 'DEFINE' or 'MOVE' omega ...\n");
00388 return;
00389 }
00390 if ( BadInput( 2, s4 ) )
00391 command = MDC_COM_IDLE;
00392 else
00393 val = (double)atof( s4 );
00394 }
00395 }
00396
00397
00398 else if(strstr(key,"IPS")) {
00399 strcpy( ips_command, buf );
00400 if ( ntok > 1 ) mar_number = atoi( s2 );
00401 if ( ntok > 2 ) mar_mode = atoi( s3 );
00402 if ( ntok > 3 ) mar_par1 = atoi( s4 );
00403 if ( ntok > 4 ) mar_par2 = atoi( s5 );
00404 if ( ntok > 5 ) mar_par3 = atoi( s6 );
00405 if ( ntok > 6 ) mar_par4 = atoi( s7 );
00406 if ( ntok > 7 ) mar_par5 = atoi( s8 );
00407 if ( ntok > 8 ) strcpy( mar_str, s8 );
00408
00409 if ( mar_number == CMD_SCAN ) {
00410 sprintf( com_root, "scan_%03d", frm++);
00411 if ( frm > 999 ) frm = 1;
00412 }
00413 if ( mar_number < 0 || mar_number > 15 ) {
00414 emit print_message(QString().sprintf("scan345: Invalid IPS number: %d\n",mar_number));
00415 emit print_message(" IPS command range is 0 to 15. ...\n");
00416 }
00417 else
00418 command = MDC_COM_IPS;
00419 }
00420
00421
00422 else if(strstr(key,"SYS")) {
00423 strcpy( ips_command, buf + strlen( s1 ) + 1);
00424 strcat( ips_command, "\r" );
00425 if ( strlen( ips_command ) > 28 ) {
00426 emit print_message("scan345: SYSTEM command must have <= 28 chars. Ignored ...\n");
00427 }
00428 else {
00429 command = MDC_COM_SHELL;
00430 }
00431 }
00432
00433
00434 else if(strstr(key,"DIST")) {
00435 if ( BadInput( 2, s2 ) )
00436 com_dist = 100.0;
00437 else
00438 com_dist = atof( s2 );
00439 }
00440
00441
00442 else if(strstr(key,"USE")) {
00443 if(strstr(s2,"SPI"))
00444 com_use_spiral = 1;
00445 }
00446
00447
00448 else if(strstr(key,"CHI")) {
00449 if ( BadInput( 2, s2 ) )
00450 com_chi = 1.0;
00451 else
00452 com_chi = atof( s2 );
00453 }
00454
00455
00456 else if(strstr(key,"THET")) {
00457 if ( BadInput( 2, s2 ) )
00458 com_theta = 1.0;
00459 else
00460 com_theta = atof( s2 );
00461 }
00462
00463
00464 else if( strstr(key,"WAVE")) {
00465 if ( BadInput( 2, s2 ) )
00466 com_wavelength = 1.541789;
00467 else
00468 com_wavelength = atof( s2 );
00469 }
00470
00471
00472 else if(strstr(key,"TIME") || strstr(key, "DOSE") ) {
00473 if ( BadInput( 2, s2 ) )
00474 com_time = 60.0;
00475 else
00476 com_time = atof( s2 );
00477 }
00478
00479
00480 else if(strstr(key,"SOUR")) {
00481 for ( i=6; i<strlen(buf); i++ ) if ( buf[i] != ' ' )break;
00482 strcpy( com_source, buf+i );
00483 }
00484
00485
00486 else if(strstr(key,"FILT")) {
00487 for ( i=6; i<strlen(buf); i++ ) if ( buf[i] != ' ' )break;
00488 strcpy( com_filter, buf+i );
00489 }
00490
00491
00492 else if(strstr(key,"REMA")) {
00493 for ( i=6; i<strlen(buf); i++ ) if ( buf[i] != ' ' )break;
00494 strcpy( com_remark, buf+i);
00495 }
00496
00497
00498 else if(strstr(key,"BEAM")) {
00499 if ( !BadInput( 2, s2 ) )
00500 com_slitx = atof( s2 );
00501 if ( !BadInput( 2, s3 ) )
00502 com_slity = atof( s3 );
00503 }
00504
00505
00506 else if(strstr(key,"POLA")) {
00507 if ( !BadInput( 2, s2 ) )
00508 com_polar = atof( s2 );
00509 }
00510
00511
00512 else if(strstr(key,"POWE")) {
00513 if ( !BadInput( 2, s2 ) )
00514 com_kV = atof( s2 );
00515 if ( !BadInput( 2, s3 ) )
00516 com_mA = atof( s3 );
00517 }
00518
00519
00520 if ( command == MDC_COM_SCAN ) {
00521
00522 strcpy( str, com_dir );
00523 if ( str[0] == '\0' || str[ strlen(str) - 1 ] == '/' )
00524 sprintf(com_dir,"%s", str);
00525 else
00526 sprintf(com_dir,"%s/", str);
00527
00528 if ( TestDirectory( com_dir ) < 1 ) {
00529 sprintf(str, "scan345: No access to directory %s\n",com_dir);
00530 emit print_message(str);
00531 goto DONE;
00532 }
00533 dfree = GetDiskSpace( com_dir );
00534 disk = (com_size*com_size + 2*com_size)/1000000.;
00535 if ( com_format == OUT_MAR || com_format == OUT_CIF || com_format == OUT_CBF )
00536 disk *= 0.4;
00537 if ( com_use_spiral )
00538 disk = disk + 1.6*disk;
00539
00540 if ( disk > dfree ) {
00541 sprintf( str, "scan345: Not enough disk space in %s!\n", com_dir );
00542 emit print_message(str);
00543 goto DONE;
00544 }
00545 }
00546
00547
00548 else if ( command == MDC_COM_IPS ) {
00549 j = sscanf( ips_command, "%s%s", s1,s2);
00550 if ( j != 2 || BadInput( 1, s2) ) {
00551 command = 0;
00552 sprintf(str, "scan345: Wrong argument 1 (%s) on IPS command\n",s2);
00553 emit print_message(str);
00554 command = 0;
00555 }
00556 }
00557
00558
00559
00560
00561 else if ( command == MDC_COM_COLL ) {
00562 if ( coll_phi == 0 ) {
00563 emit print_message("scan345: With COMMAND EXPOSURE, also keyword PHI phi_start phi_end [oscillations] must be given ...\n");
00564 command = MDC_COM_IDLE;
00565 return;
00566 }
00567 if ( coll_time == 0 ) {
00568 emit print_message("scan345: With COMMAND EXPOSURE, also keyword TIME/DOSE exposure_time/xray_dose must be given ...\n");
00569 command = MDC_COM_IDLE;
00570 return;
00571 }
00572 }
00573
00574 if ( command >= 0 )
00575 marTask( command , val );
00576 DONE:
00577 return;
00578 }
00579
00580
00581
00582
00583 int
00584 Command::BadInput(int type, char *str1)
00585 {
00586 int i,k;
00587
00588 RemoveBlanks( str1 );
00589
00590 k=strlen( str1 );
00591 if ( strlen( str1 ) < 1 ) return 1;
00592
00593 for ( i=k-1; i>=0; i-- ) {
00594
00595 if ( type == 1 && isdigit( str1[i] ) )
00596 continue;
00597
00598
00599 else if ( type == 2 && ( isdigit( str1[i] ) || str1[i] == '.' ) )
00600 continue;
00601
00602
00603 else if ( type == 3 && ( isdigit( str1[i] ) || str1[i] == '.' || str1[i] == '-' ) )
00604 continue;
00605
00606 return( 1 );
00607
00608 }
00609
00610
00611 return( 0 );
00612 }
00613
00614
00615
00616
00617 int
00618 Command::TestDirectory(char *dir)
00619 {
00620 FILE *fp;
00621 extern void RemoveBlanks();
00622
00623
00624 if ( ( strlen( dir ) == 1 && dir[0] != '/' ) ||
00625 ( strlen( dir ) == 2 && dir[0] == '.' && dir[1] == '/' ) ) {
00626 strcpy( dir, working_dir );
00627 }
00628
00629 if ( dir[ strlen(dir) - 1] == '/' )
00630 dir[ strlen(dir) - 1] = '\0';
00631 sprintf(buf,"%s/test.dir",dir);
00632
00633 if((fp=fopen(buf,"w+"))==NULL){
00634 return 0;
00635 }
00636 else {
00637 fclose(fp);
00638
00639 remove(buf);
00640
00641 return 1;
00642 }
00643 }
00644
00645
00646
00647 void
00648 Command::mar_init_params()
00649 {
00650
00651
00652 cur_scantime = cfg.scantime [stat_scanmode];
00653 cur_diameter = cfg.diameter [stat_scanmode];
00654 cur_pixelsize = cfg.pixelsize [stat_scanmode];
00655
00656 com_size = cfg.size [stat_scanmode];
00657 com_pixelsize = cur_pixelsize;
00658 com_mode = ARG_TIME;
00659 com_scanmode = stat_scanmode;
00660 com_scan_erase = 0;
00661 com_scan_add = 0;
00662
00663 com_wavelength = cfg.wavelength;
00664 com_dist = 100.;
00665 com_time = 60.;
00666 com_phiosc = 1;
00667 com_omeosc = 0;
00668 com_phibeg = cfg.phi_def;
00669 com_phiend = cfg.phi_def;
00670 com_dphi = 1.0;
00671 com_dome = 0.0;
00672 com_omebeg = cfg.ome_def;
00673 com_omeend = cfg.ome_def;
00674 com_chi = cfg.chi_def;
00675 com_theta = cfg.thet_def;
00676 com_dosebeg = 0.0;
00677 com_doseend = 0.0;
00678 com_doseavg = 0.0;
00679 com_dosesig = 0.0;
00680 com_dosemin = 0.0;
00681 com_dosemax = 0.0;
00682 com_dosen = 0;
00683 com_use_spiral = 0;
00684 com_format = OUT_MAR;
00685 com_polar = cfg.polar;
00686 com_slitx = cfg.slitx;
00687 com_slity = cfg.slity;
00688 com_kV = cfg.kV;
00689 com_mA = cfg.mA;
00690
00691 strcpy( com_filter, cfg.filter );
00692 strcpy( com_source, cfg.source );
00693 strcpy( com_remark, "" );
00694 strcpy( com_root, "xtal" );
00695 strcpy( com_dir, working_dir );
00696 }