- Timestamp:
- Feb 28, 2020 3:01:37 PM (3 years ago)
- Location:
- sans/Dev/trunk/NCNR_User_Procedures/Reduction
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/EventModeProcessing.ipf
r1115 r1241 995 995 if(strsearch(igorKindStr, "64", 0 ) != -1) 996 996 alertStr = "The Event Loader XOP is not installed for the 64-bit version of Igor. Without it, event loading will " 997 alertStr += "be slow. It is recommended that you re-run the NCNR Installer. Click YESto stop and "998 alertStr += "do the installation, or NOto continue with the file loading."997 alertStr += "be slow. It is recommended that you re-run the NCNR Installer. Click NO to stop and " 998 alertStr += "do the installation, or YES to continue with the file loading." 999 999 else 1000 1000 alertStr = "The Event Loader XOP is not installed for the 32-bit version of Igor. Without it, event loading will " 1001 alertStr += "be slow. It is recommended that you re-run the NCNR Installer. Click YESto stop and "1002 alertStr += "do the installation, or NOto continue with the file loading."1001 alertStr += "be slow. It is recommended that you re-run the NCNR Installer. Click NO to stop and " 1002 alertStr += "do the installation, or YES to continue with the file loading." 1003 1003 endif 1004 1004 DoAlert 1,alertStr 1005 1005 1006 if(V_flag == 1)1006 if(V_flag == 0) 1007 1007 // get out gracefully 1008 1008 SetDataFolder root: 1009 1009 return(0) 1010 1010 endif 1011 1012 LoadEvents() 1011 1012 LoadEvents_New_noXOP() 1013 // LoadEvents() 1014 1015 1013 1016 #endif 1014 1017 … … 1028 1031 if(mode == MODE_STREAM) // continuous "Stream" mode - start from zero 1029 1032 Duplicate/O timePt rescaledTime 1030 rescaledTime = 1e-7*(timePt-timePt[0]) //convert to seconds and start from zero1033 MultiThread rescaledTime = 1e-7*(timePt-timePt[0]) //convert to seconds and start from zero 1031 1034 t_longest = waveMax(rescaledTime) //should be the last point 1032 1035 endif … … 1034 1037 if(mode == MODE_OSCILL) // oscillatory mode - don't adjust the times, we get periodic t0 to reset t=0 1035 1038 Duplicate/O timePt rescaledTime 1036 rescaledTime *= 1e-7 //convert to seconds and that's all1039 MultiThread rescaledTime *= 1e-7 //convert to seconds and that's all 1037 1040 t_longest = waveMax(rescaledTime) //if oscillatory, won't be the last point, so get it this way 1038 1041 … … 1044 1047 if(mode == MODE_TISANE) // TISANE mode - don't adjust the times, we get periodic t0 to reset t=0 1045 1048 Duplicate/O timePt rescaledTime 1046 rescaledTime *= 1e-7 //convert to seconds and that's all1049 MultiThread rescaledTime *= 1e-7 //convert to seconds and that's all 1047 1050 t_longest = waveMax(rescaledTime) //if oscillatory, won't be the last point, so get it this way 1048 1051 … … 1053 1056 if(mode == MODE_TOF) // TOF mode - don't adjust the times, we get periodic t0 to reset t=0 1054 1057 Duplicate/O timePt rescaledTime 1055 rescaledTime *= 1e-7 //convert to seconds and that's all1058 MultiThread rescaledTime *= 1e-7 //convert to seconds and that's all 1056 1059 t_longest = waveMax(rescaledTime) //if oscillatory, won't be the last point, so get it this way 1057 1060 … … 1281 1284 // statements and flags are kept for this reason, so the code is a bit messy. 1282 1285 // 1283 Function LoadEvents ()1286 Function LoadEvents_OLD() 1284 1287 1285 1288 NVAR time_msw = root:Packages:NIST:Event:gEvent_time_msw … … 3583 3586 LoadEvents_XOP() 3584 3587 #else 3585 LoadEvents() 3588 LoadEvents_New_noXOP() 3589 // LoadEvents() 3586 3590 #endif 3587 3591 … … 3594 3598 3595 3599 Duplicate/O timePt rescaledTime 3596 rescaledTime = 1e-7*(timePt-timePt[0]) //convert to seconds and start from zero3600 MultiThread rescaledTime = 1e-7*(timePt-timePt[0]) //convert to seconds and start from zero 3597 3601 t_longest = waveMax(rescaledTime) //should be the last point 3598 3602 … … 4397 4401 End 4398 4402 4403 4404 ///////////////////////////////// 4405 // 4406 // 4407 // Improved loading of SANS Event files 4408 // without the use of an XOP (in case macOS / Igor XOPs can't be loaded) 4409 // 4410 // 28 FEB 2020 SRK 4411 // 4412 4413 // TODO 4414 // -- still need to clean this up to provide an identical entry point and functionality 4415 // to the existing non-XOP loader 4416 // -- all routines need to be made DataFolder aware. currently everything is in root: 4417 // -- all waves need to be explicitly declared. currently the assumption is that they exist, in root: 4418 // -- be sure that global variables are declared and set with the loaded values (t_max, values for status) 4419 // -- clean up (kill) anything not needed so that I can save memory 4420 4421 4422 4423 // 4424 // 4425 // this now works properly and with reasonable speed: 4426 // relative times: 4427 // XOP = 1 4428 // old Igor code = 28 4429 // this new code = 6.3 4430 // 4431 // loaded variables, times, XY location have all been verified vs. XOP and old Igor routines 4432 // 4433 4434 // this code loads 563 MB in 114 s (as predicted by scaling up XOP load speed) 4435 // loads 979 MB in 266 s (slower than predicted) 4436 4437 4438 Function LoadEvents_New_noXOP() 4439 4440 SVAR fname = root:Packages:NIST:Event:gEvent_logfile 4441 4442 Variable numBad = 0 4443 4444 // String fname = DoOpenFileDialog("select an event file") 4445 4446 tic() 4447 LoadEventAsHex(fname) 4448 Wave/T/Z newWave = root:Packages:NIST:Event:newWave 4449 4450 RemoveFFF(newWave) 4451 4452 GetBitsFromEvents() 4453 Wave/Z bit29 = root:Packages:NIST:Event:bit29 4454 Wave/Z events = root:Packages:NIST:Event:events 4455 Wave/Z time_lsw = root:Packages:NIST:Event:time_lsw 4456 Wave/Z type = root:Packages:NIST:Event:type 4457 Wave/Z xloc = root:Packages:NIST:Event:xloc 4458 Wave/Z yloc = root:Packages:NIST:Event:yloc 4459 4460 numBad = CleanUpBeginning(type,events,bit29,xloc,yloc,time_lsw) 4461 4462 DecodeEvents_New(type,events,bit29,xloc,yloc,time_lsw,numBad) 4463 Wave/Z timePt = root:Packages:NIST:Event:timePt 4464 Wave/Z deletePtFlag = root:Packages:NIST:Event:deletePtFlag 4465 4466 // 4467 // see the trick for setting the deletePtFlag wave that I use in DecodeEvents_New 4468 // -- I needed to do this since the sort operation does not preserve the order of 4469 // any items with the same value --- from the help file: 4470 // "The algorithm used does not maintain the relative position of items with the same key value." 4471 // 4472 // 4473 Sort deletePtFlag,bit29,events,timePt,time_lsw,type,xloc,yloc,deletePtFlag 4474 // FindValue/I=10 deletePtFlag //bad points are flagged as 1, first real point is 10 (unless it was replaced) 4475 // Print V_Value //so this will fail... 4476 4477 FindLevel/P/Q deletePtFlag 10 4478 // Print V_LevelX 4479 4480 DeletePoints 0,trunc(V_LevelX)+1, bit29,events,timePt,time_lsw,type,xloc,yloc,deletePtFlag 4481 4482 SetDataFolder root:Packages:NIST:Event: 4483 4484 // this is done after the file load/decode whether the XOP was used or the Igor code 4485 // (don't do the time rescaling here) 4486 // Duplicate/O timePt rescaledTime 4487 // // MultiThread shaves off significant time! 4488 // MultiThread rescaledTime *= 1e-7 //convert to seconds and that's all 4489 4490 4491 // cleanup as many waves as possible to save space 4492 // these can be kept as needed for debugging 4493 KillWaves/Z bit29,type,time_lsw,events,deletePtFlag 4494 KillWaves/Z badTimePt,badEventNum,PPTime,PPEventNum,T0Time,T0EventNum 4495 toc() 4496 4497 SetDataFolder root: 4498 return(0) 4499 end 4500 4501 //Macro doDecodeOnly() 4502 // Variable numBad=0 4503 // DecodeEvents_New(type,events,bit29,xloc,yloc,time_lsw,numBad) 4504 //End 4505 4506 Function LoadEventAsHex(fname) 4507 String fname 4508 4509 SetDataFolder root:Packages:NIST:Event: 4510 4511 LoadWave/J/O/A/K=2/B="C=1,F=10,T=96,N=newWave;" fname // /E=1 flag will display a table 4512 4513 // table is useful to see as hexadecimal -- every other point 4514 // is FFFFFFFF = 4294967295 and is garbage to delete 4515 4516 SetDataFolder root: 4517 return(0) 4518 end 4519 4520 // no need to remove every other point that is zero 4521 // (actually 4294967295 = FFFFFFFF) 4522 // I can to this with a wave assignment 4523 Function RemoveFFF(w) 4524 Wave w 4525 4526 SetDataFolder root:Packages:NIST:Event: 4527 // RemoveZeroEvents(w) 4528 4529 // 32 bit unsigned integer wave 4530 Make/O/U/I/N=(trunc(numpnts(w))/2) events 4531 MultiThread events = w[2*p] 4532 4533 KillWaves/Z w //not needed any longer 4534 4535 SetDataFolder root: 4536 return(0) 4537 End 4538 4539 4540 4541 Function GetBitsFromEvents() 4542 4543 // Wave events=events 4544 SetDataFolder root:Packages:NIST:Event: 4545 Wave events = root:Packages:NIST:Event:events 4546 4547 Make/O/U/B/N=(numpnts(events)) xloc,yloc,type,bit29 4548 Make/O/U/I/N=(numpnts(events)) time_lsw 4549 4550 MultiThread type = (events & 0xC0000000)/1073741824 //right shift by 2^30 4551 4552 MultiThread bit29 = (events & 0x20000000)/536870912 //bit 29 only , shift by 2^29 4553 4554 MultiThread xloc = 127 - (events & 255) //last 8 bits (7-0) 4555 MultiThread yloc = (events & 65280)/256 //bits 15-8, right shift by 2^8 4556 4557 4558 MultiThread time_lsw = (events & 536805376)/65536 //13 bits, 28-16, right shift by 2^16 4559 4560 Variable/G numXYevents,num0,num1,num2,num3 4561 num0 = CountType(0) 4562 num1 = CountType(1) 4563 num2 = CountType(2) 4564 num3 = CountType(3) 4565 4566 numXYevents = num0 + num2 4567 Printf "numXYevents = type 0 + type 2 = %d\r",numXYevents 4568 Printf "XY = num0 = %d\r",num0 4569 Printf "time MSW = num1 = %d\r",num1 4570 Printf "XY time = num2 = %d\r",num2 4571 Printf "Rollover = num3 = %d\r",num3 4572 4573 4574 // dispStr will be displayed on the panel 4575 SVAR dispStr = root:Packages:NIST:Event:gEventDisplayString 4576 SVAR filepathStr = root:Packages:NIST:Event:gEvent_logfile 4577 4578 String tmpStr="",fileStr="" 4579 fileStr = ParseFilePath(0, filepathstr, ":", 1, 0) 4580 4581 Variable fileref,totBytes 4582 Open/R fileref as filepathstr 4583 FStatus fileref 4584 Close fileref 4585 4586 totBytes = V_logEOF 4587 4588 sprintf tmpStr, "%s: %d total bytes\r",fileStr,totBytes 4589 dispStr = tmpStr 4590 sprintf tmpStr,"numXYevents = %d\r",numXYevents 4591 dispStr += tmpStr 4592 // sprintf tmpStr,"PP = %d : ",numPP 4593 // dispStr += tmpStr 4594 // sprintf tmpStr,"ZeroData = %d\r",numZero 4595 // dispStr += tmpStr 4596 sprintf tmpStr,"Rollover = %d",num3 4597 dispStr += tmpStr 4598 4599 4600 // Print 127 - (events[5] & 255) 4601 // Print (events[5] & 65280)/256 4602 4603 SetDataFolder root: 4604 return(0) 4605 End 4606 4607 // 4608 // a quick way to count the number of a particular value in a wave 4609 // 4610 Function CountType(val) 4611 Variable val 4612 4613 Wave type=type 4614 // can't duplicate, since Byte data can't accept NaN 4615 Make/O/D/N=(numpnts(type)) tmp 4616 MultiThread tmp = type 4617 4618 MultiThread tmp = (tmp[p] == val) ? NaN : tmp[p] // replace matches with NaN 4619 4620 WaveStats/Q tmp 4621 4622 KillWaves/Z tmp 4623 return(V_numNaNs) 4624 End 4625 4626 Function CleanUpBeginning(type,events,bit29,xloc,yloc,time_lsw) 4627 Wave type,events,bit29,xloc,yloc,time_lsw 4628 4629 // for all of the waves, remove points from the beginning up to the 4630 // first one with a type==2 so that I know that the 4631 // time has been properly reset to start 4632 4633 variable ii,num 4634 num=numpnts(type) 4635 for(ii=0;ii<num;ii+=1) 4636 if(type[ii] == 2) 4637 break 4638 endif 4639 endfor 4640 4641 Print "Num bad removed from beginning = ",ii 4642 DeletePoints 0,ii, type,events,bit29,xloc,yloc,time_lsw 4643 4644 return(ii) 4645 End 4646 4647 4648 // 4649 // for the bit shifts, see the decimal-binary conversion 4650 // http://www.binaryconvert.com/convert_unsigned_int.html 4651 // 4652 // K0 = 536870912 4653 // Print (K0 & 0x08000000)/134217728 //bit 27 only, shift by 2^27 4654 // Print (K0 & 0x10000000)/268435456 //bit 28 only, shift by 2^28 4655 // Print (K0 & 0x20000000)/536870912 //bit 29 only, shift by 2^29 4656 // 4657 // This is duplicated by the XOP, but the Igor code allows quick access to print out 4658 // all of the gory details of the events and every little bit of them. the print 4659 // statements and flags are kept for this reason, so the code is a bit messy. 4660 // 4661 // 4662 //Static Constant ATXY = 0 4663 //Static Constant ATXYM = 2 4664 //Static Constant ATMIR = 1 4665 //Static Constant ATMAR = 3 4666 // 4667 // 4668 Function DecodeEvents_New(type,events,bit29,xloc,yloc,time_lsw,numBad) 4669 Wave type,events,bit29,xloc,yloc,time_lsw 4670 Variable numBad // number of bad points previously removed from beginning of file 4671 4672 // NVAR time_msw = root:Packages:NIST:Event:gEvent_time_msw 4673 // NVAR time_lsw = root:Packages:NIST:Event:gEvent_time_lsw 4674 NVAR t_longest = root:Packages:NIST:Event:gEvent_t_longest 4675 4676 // SVAR filepathstr = root:Packages:NIST:Event:gEvent_logfile 4677 SVAR dispStr = root:Packages:NIST:Event:gEventDisplayString 4678 4679 SetDataFolder root:Packages:NIST:Event 4680 4681 4682 variable ii,num,typ 4683 Variable nRoll,roll_time,time_msw,timeval 4684 Variable tmpPP,tmpT0,numRemoved,rolloverHappened 4685 Variable tmpX,tmpY 4686 4687 // tic() 4688 // 32-bit unsigned, max value = 4,294,926,295 (= max number of events I can sort) 4689 Make/O/I/U/N=(numpnts(type)) deletePtFlag 4690 MultiThread deletePtFlag = p+10 // give them all a different number, starting from 10 4691 // flagged "bad" points will be set == 1 4692 4693 Make/O/N=500000 badTimePt,badEventNum,PPTime,PPEventNum,T0Time,T0EventNum 4694 MultiThread badTimePt=0 4695 MultiThread badEventNum=0 4696 MultiThread PPTime=0 4697 MultiThread PPEventNum=0 4698 MultiThread T0Time=0 4699 MultiThread T0EventNum=0 4700 4701 tmpPP=0 4702 tmpT0=0 4703 numRemoved=0 4704 4705 Make/O/D/N=(numpnts(time_lsw)) timePt 4706 MultiThread timePt = 0 //need DP wave for time, time_lsw is 32 bit int 4707 4708 4709 nRoll = 0 //number of rollover events 4710 roll_time = 2^26 //units of 10-7 sec 4711 time_msw=0 4712 4713 NVAR removeBadEvents = root:Packages:NIST:Event:gRemoveBadEvents 4714 4715 num=numpnts(type) 4716 4717 // 4718 // NOTE: I now have the types in 0123 order in the switch - so they will 4719 // appear different than the old Igor code which was 0132 4720 // 4721 4722 for(ii=0;ii<num;ii+=1) 4723 // if(mod(ii,10000)==0) 4724 // Print "step %g of %g",ii,num 4725 // endif 4726 4727 typ = type[ii] 4728 4729 switch(typ) 4730 case ATXY: 4731 4732 // if the datavalue is == 0, just skip it now (it can only be interpreted as type 0, obviously) 4733 if(events[ii] == 0 && RemoveBadEvents == 1) 4734 numRemoved += 1 4735 // Print "zero at ii= ",ii 4736 4737 // flag for deletion later 4738 deletePtFlag[ii] = 1 4739 4740 // DeletePoints ii,1, type,events,bit29,xloc,yloc,time_lsw,timePt 4741 // num -= 1 4742 // ii -= 1 4743 4744 break //don't increment ii 4745 endif 4746 4747 //if bit29=1, it's pileup, delete the point, decrement ii and num and break out 4748 if(bit29[ii] == 1) 4749 PPTime[tmpPP] = timeval 4750 PPEventNum[tmpPP] = ii 4751 tmpPP += 1 4752 numRemoved += 1 4753 // flag for deletion later 4754 deletePtFlag[ii] = 1 4755 // DeletePoints ii,1, type,events,bit29,xloc,yloc,time_lsw,timePt 4756 // num -= 1 4757 // ii -= 1 4758 break 4759 endif 4760 4761 //otherwise the point is good, calculate the time 4762 timePt[ii] = trunc( nRoll*roll_time + (time_msw * (8192)) + time_lsw[ii] ) //left shift msw by 2^13, then add in lsw, as an integer 4763 if (timePt[ii] > t_longest) 4764 t_longest = timePt[ii] 4765 endif 4766 4767 // catch the "bad" events: 4768 // if an XY event follows a rollover, time_msw is 0 by definition, but does not immediately get 4769 // re-evalulated here. Throw out only the immediately following points where msw is still 8191 4770 if(rolloverHappened && RemoveBadEvents == 1) 4771 // maybe a bad event, throw it out 4772 if(time_msw == 8191) 4773 badTimePt[numBad] = timeVal 4774 badEventNum[numBad] = ii 4775 numBad +=1 4776 numRemoved += 1 4777 // flag for deletion later 4778 deletePtFlag[ii] = 1 4779 // DeletePoints ii,1, type,events,bit29,xloc,yloc,time_lsw,timePt 4780 // num -= 1 4781 // ii -= 1 4782 else 4783 // time_msw has been reset, points are good now, so keep this one 4784 rolloverHappened = 0 4785 endif 4786 endif 4787 4788 break 4789 4790 case ATMIR: // 1 4791 4792 time_msw = (events[ii] & 536805376)/65536 //13 bits, 28-16, right shift by 2^16 4793 timePt[ii] = trunc( nRoll*roll_time + (time_msw * (8192)) + time_lsw[ii] ) 4794 if (timePt[ii] > t_longest) 4795 t_longest = timePt[ii] 4796 endif 4797 4798 if(bit29[ii] != 0) // bit 29 set is a T0 event, not a rollover 4799 //Printf "bit29 = 1 at ii = %d : type = %d\r",ii,type 4800 T0Time[tmpT0] = time_lsw[ii] 4801 T0EventNum[tmpT0] = ii 4802 tmpT0 += 1 4803 // reset nRoll = 0 for calcluating the time 4804 nRoll = 0 4805 endif 4806 4807 // previous event was "2" (kept XY from there) 4808 // 4809 xloc[ii] = tmpX 4810 yloc[ii] = tmpY 4811 4812 break 4813 case ATXYM: // 2 4814 4815 // 4816 // keep only the XY position, next event will be ATMIR 4817 // where these XY points will be written 4818 // 4819 tmpX = xloc[ii] 4820 tmpY = yloc[ii] 4821 // flag for deletion later 4822 deletePtFlag[ii] = 1 4823 // DeletePoints ii,1, type,events,bit29,xloc,yloc,time_lsw ,timePt 4824 // num -= 1 4825 // ii -= 1 4826 4827 // next event must be ATMIR (type 1) that will contain the MSW time bits 4828 break 4829 case ATMAR: // 3 4830 4831 nRoll += 1 4832 4833 if(bit29[ii] != 0) // bit 29 set is a T0 event, not a rollover 4834 //Printf "bit29 = 1 at ii = %d : type = %d\r",ii,type 4835 T0Time[tmpT0] = time_lsw[ii] 4836 T0EventNum[tmpT0] = ii 4837 tmpT0 += 1 4838 // reset nRoll = 0 for calcluating the time 4839 nRoll = 0 4840 endif 4841 4842 rolloverHappened = 1 4843 4844 // delete the point since it's not XY 4845 // flag for deletion later 4846 deletePtFlag[ii] = 1 4847 // DeletePoints ii,1, type,events,bit29,xloc,yloc,time_lsw ,timePt 4848 // num -= 1 4849 // ii -= 1 4850 4851 break 4852 default: 4853 endswitch 4854 4855 endfor 4856 4857 // printf("Igor new method full file decode done in ") 4858 // toc() 4859 4860 Print "Events removed (Igor) = ",numRemoved 4861 4862 Variable numXYEvents = numpnts(xloc) 4863 String tmpStr="" 4864 4865 sPrintf tmpStr,"\rBad Rollover Events = %d (%4.4g %% of events)",numBad,numBad/numXYevents*100 4866 dispStr += tmpStr 4867 sPrintf tmpStr,"\rTotal Events Removed = %d (%4.4g %% of events)",numRemoved,numRemoved/numXYevents*100 4868 dispStr += tmpStr 4869 SetDataFolder root: 4870 4871 4872 return(0) 4873 4874 end 4875 4876 // not used any longer since the one-by-one deletion of points is 4877 // WAY too slow to use for any event files of > 50 MB 4878 Function RemoveZeroEvents(events) 4879 Wave events 4880 4881 // start at the back and remove zeros 4882 Variable num=numpnts(events),ii,numToRemove,count 4883 4884 count = 0 4885 numToRemove = 2 //remove the zero, and the following FFFFFF 4886 ii=num 4887 do 4888 ii -= 1 4889 if(events[ii] == 0) 4890 DeletePoints ii, numToRemove, events 4891 count += 1 4892 endif 4893 while(ii > 0) 4894 4895 print "removed zero events = ",count 4896 return(count) 4897 End 4898 4899 ////////////////////////////// -
sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/SANS_Utilities.ipf
r1017 r1241 26 26 27 27 function tic() 28 variable/G tictoc = startMSTimer28 variable/G root:tictoc = startMSTimer 29 29 end 30 30 31 31 function toc() 32 NVAR/Z tictoc 32 NVAR/Z tictoc = root:tictoc 33 33 variable ttTime = stopMSTimer(tictoc) 34 34 printf "%g seconds\r", (ttTime/1e6) -
sans/Dev/trunk/NCNR_User_Procedures/Reduction/VSANS/V_Transmission.ipf
r1209 r1241 185 185 // this resets a global string, since I can't pass a parameter (only constants) in value=fn() 186 186 // PopupMenu popup_0,mode=1,value=#gSamMatchList 187 PopupMenu popup_0,mode=1, value=V_getSamListForPopup()187 PopupMenu popup_0,mode=1,win=V_TransmissionPanel,value=V_getSamListForPopup() 188 188 189 189 190 190 // then pop the sample list with the top file to see that it is a match for the transmission file 191 191 STRUCT WMPopupAction samPopAct 192 ControlInfo popup_0192 ControlInfo/W=V_TransmissionPanel popup_0 193 193 samPopAct.popStr = S_Value // the top file 194 194 V_TSamFilePopMenuProc(samPopAct) … … 218 218 219 219 String transStr 220 ControlInfo popup_1 //the transmission file popup220 ControlInfo/W=V_TransmissionPanel popup_1 //the transmission file popup 221 221 transStr = S_Value 222 222 … … 251 251 252 252 String openStr 253 ControlInfo popup_2 //the open beam popup253 ControlInfo/W=V_TransmissionPanel popup_2 //the open beam popup 254 254 openStr = S_Value 255 255
Note: See TracChangeset
for help on using the changeset viewer.