CMeasure.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. using System.Collections.Generic;
  2. using OTSDataType;
  3. using System;
  4. using System.Drawing;
  5. using static OTSDataType.otsdataconst;
  6. using OTSModelSharp.ImageProcess;
  7. using OTSModelSharp.ServiceInterface;
  8. namespace OTSModelSharp
  9. {
  10. // enum and struct used for send message to App
  11. public enum ENUM_MSG_TYPE
  12. {
  13. MTHREADSTATUS = 1001,
  14. MSAMPLESTATUS = 1002,
  15. MSAMPLERESULT = 1003
  16. };
  17. public enum MSAMPLE_RET
  18. {
  19. BSE_DATA = 0,
  20. FIELD_DATA = 1,
  21. START_MSR_FIELD = 2
  22. };
  23. public struct SMSR_COMPLETE_DATA
  24. {
  25. public OTS_MSR_THREAD_STATUS MsrStatus;
  26. public string csMsrStartTime;
  27. public int iMsrCompleteSampleCount;
  28. public int iMsrCompleteFieldCount;
  29. public int iParticleCount;
  30. public TimeSpan MsrUsedTime;
  31. public string csMsrEndTime;
  32. };
  33. public struct STMThreadStatus
  34. {
  35. public OTS_MSR_THREAD_STATUS iMsrStatu; //OTS_MSR_THREAD_STATUS
  36. public string csMsrStartTime; //MSR_START_TIME
  37. public string csMsrEndTime; //MSR_END_TIME
  38. public SMSR_COMPLETE_DATA SMsrCompleteData;
  39. };
  40. public struct STMSampleStatus
  41. {
  42. public OTS_MSR_SAMPLE_STATUS iMsrSampleStatu; //OTS_MSR_SAMPLE_STATUS
  43. public string cSampleName;
  44. public string csSampleMsrStartTime;
  45. public List<Point> BCompleteFieldList;
  46. };
  47. public struct STMSampleResultData
  48. {
  49. public MSAMPLE_RET iRetDataType; //ENUM_MEASURE_SAMPLE_RESULT
  50. public struct RBSEDATA
  51. {
  52. public System.Drawing.Point pos;
  53. public int iBSEDataHeight;
  54. public int iBSEDataWidth;
  55. public byte[] lpBSEData;
  56. };
  57. public struct SAMPLEFIELDDATA
  58. {
  59. public System.Drawing.Point FieldPos;
  60. public int iMeasureFieldCount;
  61. public int iCompleteFieldCount;
  62. public int iSParticleCount; // Field particle count
  63. public TimeSpan TUsedTime;
  64. };
  65. public struct StartToMsrField
  66. {
  67. public System.Drawing.Point FieldPos;
  68. };
  69. public RBSEDATA BSEData;
  70. public SAMPLEFIELDDATA SFieldData;
  71. public StartToMsrField SMsrField;
  72. };
  73. public struct ST_MSTMsg
  74. {
  75. public ENUM_MSG_TYPE iMsgType;
  76. public STMThreadStatus STMThreadStu;
  77. public STMSampleStatus STMSampleStu;
  78. public STMSampleResultData STMSampleRetData;
  79. };
  80. public class CMeasure
  81. {
  82. private const string UNTITLED_FILE_NAME = "Untitled";
  83. public delegate void ProgressEventHandler(ST_MSTMsg msg);
  84. public event ProgressEventHandler ProgressEvent;
  85. COTSMsrPrjResultData m_pProjData;
  86. List< COTSSample> m_listMeasurableSamples=new List<COTSSample>();
  87. string m_strWorkingFolder;
  88. CMsrThreadStatus m_ThreadStatus;
  89. SemController m_SemController;// there is no correspondense clr,so use this instead temporarilly
  90. protected static NLog.Logger loger = NLog.LogManager.GetCurrentClassLogger();
  91. public SortedDictionary<string, CSmplMeasure> mapSmplMsr = new SortedDictionary<string, CSmplMeasure>();//use this map to hold all the smplMeasure object
  92. public List<COTSSample> GetListMeasurableSamples()
  93. {
  94. return m_listMeasurableSamples;
  95. }
  96. public void SetListMeasurableSamples(List<COTSSample> value)
  97. {
  98. m_listMeasurableSamples = value;
  99. }
  100. public CMeasure()
  101. {
  102. m_strWorkingFolder = "";
  103. m_ThreadStatus = new CMsrThreadStatus();
  104. m_SemController = SemController.GetSEMController();
  105. }
  106. public COTSMsrPrjResultData GetProjResultData()
  107. {
  108. return m_pProjData;
  109. }
  110. public ISemController GetSEMController()
  111. {
  112. // get SEM, scanner and x-ray controller via hardware manager
  113. return m_SemController;
  114. }
  115. public CMsrThreadStatus GetMsrThreadStatus() { return m_ThreadStatus; }
  116. public void Init(COTSMsrPrjResultData a_pProjMgrFile)
  117. {
  118. m_pProjData = a_pProjMgrFile;
  119. SetListMeasurableSamples(a_pProjMgrFile.GetSampleList());
  120. return ;
  121. }
  122. void ThreadOver()
  123. {
  124. DateTime timeEnd = m_ThreadStatus.GetEndTime();
  125. ST_MSTMsg MsrMsg = new ST_MSTMsg();
  126. MsrMsg.iMsgType = ENUM_MSG_TYPE.MTHREADSTATUS;
  127. MsrMsg.STMThreadStu.iMsrStatu = m_ThreadStatus.GetStatus();
  128. MsrMsg.STMThreadStu.csMsrEndTime = timeEnd.ToString("yyyy-MM-dd HH:mm:ss");
  129. ProgressEvent(MsrMsg);
  130. }
  131. void ThreadOverWithoutDisConnect()
  132. {
  133. DateTime timeEnd = m_ThreadStatus.GetEndTime();
  134. ST_MSTMsg MsrMsg = new ST_MSTMsg();
  135. MsrMsg.iMsgType = ENUM_MSG_TYPE.MTHREADSTATUS;
  136. MsrMsg.STMThreadStu.iMsrStatu = m_ThreadStatus.GetStatus();
  137. MsrMsg.STMThreadStu.csMsrEndTime = timeEnd.ToString("yyyy-MM-dd HH:mm:ss");
  138. ProgressEvent(MsrMsg);
  139. }
  140. void SetWorkingFolderStr()
  141. {
  142. // get project file pathname
  143. string strSettingFilePathName = m_pProjData.GetPathName();
  144. strSettingFilePathName.Trim();
  145. if (strSettingFilePathName == "")
  146. {
  147. loger .Error("SetWorkingFolderStr: project file pathname is an empty string");
  148. return ;
  149. }
  150. else if (strSettingFilePathName==UNTITLED_FILE_NAME)
  151. {
  152. loger .Error ("SetWorkingFolderStr: project file pathname is an invalid string");
  153. return ;
  154. }
  155. // working folder string
  156. m_strWorkingFolder = FileHelper.GetFolderName(strSettingFilePathName);
  157. return ;
  158. }
  159. public void SendMessageToMeasureApp(ST_MSTMsg msg)
  160. {
  161. ProgressEvent(msg);
  162. }
  163. public bool IsMeasureStopped()
  164. {
  165. return m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.STOPPED;
  166. }
  167. public bool IsMeasureRunning() { return m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.INPROCESS; }
  168. public bool IsMeasureFailed() { return m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.FAILED; }
  169. public bool IsMeasureCompleted() { return m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.COMPLETED; }
  170. public void DoMeasure()
  171. {
  172. // start measurement, creat thread measure status class, let the main thread know that measurement started
  173. m_ThreadStatus.SetStartTime(System.DateTime.Now);
  174. DateTime timeStart = m_ThreadStatus.GetStartTime();
  175. ST_MSTMsg MsgMsrStart=new ST_MSTMsg();
  176. MsgMsrStart.iMsgType = ENUM_MSG_TYPE.MTHREADSTATUS;
  177. MsgMsrStart.STMThreadStu.iMsrStatu = OTS_MSR_THREAD_STATUS.INPROCESS;
  178. MsgMsrStart.STMThreadStu.csMsrStartTime = timeStart.ToShortDateString();
  179. ProgressEvent (MsgMsrStart);
  180. loger.Info("Measurement started!");
  181. // connect hardware
  182. loger.Info("Connect SEM!");
  183. if (!m_SemController.Connect())
  184. {
  185. loger .Error("DoMeasure: failed to connect hardware.");
  186. m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.FAILED);
  187. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  188. ThreadOver();
  189. return;
  190. }
  191. // set working directory which is the same directory of the setting file
  192. SetWorkingFolderStr();
  193. List <string > listMeasuredSamples = m_ThreadStatus.GetCompletedSamples();
  194. // got through measure list
  195. foreach (var pSample in GetListMeasurableSamples())
  196. {// check and break if stop button is clicked
  197. if (m_ThreadStatus.GetStatus()== OTS_MSR_THREAD_STATUS.STOPPED )
  198. {
  199. // stop button clicked
  200. loger .Info("DoMeasure: stop button is clicked.");
  201. // record end time
  202. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  203. ThreadOver();
  204. return;
  205. }
  206. if (!pSample.GetSwitch())
  207. {
  208. continue;
  209. }
  210. CSmplMeasure pSmplMeasure;
  211. if (!mapSmplMsr.ContainsKey(pSample.GetName()))
  212. {// create a sample measure object for the sample
  213. switch (m_pProjData.m_nPackId)
  214. {
  215. case OTS_SysType_ID.IncA:
  216. pSmplMeasure = new CSmplMeasureInclution(m_strWorkingFolder, pSample);
  217. break;
  218. case OTS_SysType_ID.CleannessA:
  219. pSmplMeasure = new CSmplMeasureCleanliness(m_strWorkingFolder, pSample);
  220. break;
  221. default:
  222. pSmplMeasure = new CSmplMeasureInclution(m_strWorkingFolder, pSample);
  223. break;
  224. }
  225. // set measure thread
  226. pSmplMeasure.SetMsrThread(this);
  227. mapSmplMsr[pSample.GetName()] = pSmplMeasure;
  228. }
  229. else
  230. {
  231. pSmplMeasure = mapSmplMsr[pSample.GetName()];
  232. pSample.GetMsrStatus().SetStatus(OTS_MSR_SAMPLE_STATUS.INPROCESS);
  233. m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.INPROCESS);
  234. }
  235. pSmplMeasure.DoMeasureForOneSample();
  236. // check if measurement is successful
  237. if (pSample.GetMsrStatus().GetStatus() == OTS_MSR_SAMPLE_STATUS.PAUSED)
  238. {// record end time
  239. m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.PAUSED);
  240. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  241. // update thread measure status class, let the main thread know that this sample measurement stopped
  242. ST_MSTMsg MsgSmpStop = new ST_MSTMsg();
  243. MsgSmpStop.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  244. MsgSmpStop.STMThreadStu.iMsrStatu = OTS_MSR_THREAD_STATUS.PAUSED;
  245. MsgSmpStop.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.PAUSED;
  246. MsgSmpStop.STMThreadStu.csMsrEndTime = DateTime.Now.ToShortDateString();
  247. MsgSmpStop.STMThreadStu.iMsrStatu = OTS_MSR_THREAD_STATUS.PAUSED;
  248. ProgressEvent(MsgSmpStop);
  249. ThreadOver();
  250. return;
  251. }else if (pSample.GetMsrStatus().GetStatus() == OTS_MSR_SAMPLE_STATUS.STOPPED)
  252. {// record end time
  253. m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.STOPPED);
  254. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  255. // update thread measure status class, let the main thread know that this sample measurement stopped
  256. ST_MSTMsg MsgSmpStop = new ST_MSTMsg();
  257. MsgSmpStop.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  258. MsgSmpStop.STMThreadStu.iMsrStatu= OTS_MSR_THREAD_STATUS.STOPPED;
  259. MsgSmpStop.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.STOPPED;
  260. MsgSmpStop.STMThreadStu.csMsrEndTime = DateTime .Now .ToShortDateString();
  261. MsgSmpStop.STMThreadStu.iMsrStatu= OTS_MSR_THREAD_STATUS.STOPPED;
  262. ProgressEvent(MsgSmpStop);
  263. ThreadOver();
  264. return;
  265. }
  266. else if (pSample.GetMsrStatus().GetStatus() == OTS_MSR_SAMPLE_STATUS.FAILED)
  267. {
  268. // measurement failed
  269. m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.FAILED);
  270. // record end time
  271. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  272. // update thread measure status class, let the main thread know that this sample measurement failed
  273. ST_MSTMsg MsgSmpFailed=new ST_MSTMsg();
  274. MsgSmpFailed.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  275. MsgSmpFailed.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.FAILED;
  276. ProgressEvent(MsgSmpFailed);
  277. ThreadOver();
  278. return;
  279. }
  280. // record end time
  281. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  282. // update thread measure status class, let the main thread know that this sample measurement successes
  283. ST_MSTMsg MsgSmpSuccess=new ST_MSTMsg();
  284. MsgSmpSuccess.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  285. MsgSmpSuccess.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.SUCCESSED;
  286. ProgressEvent(MsgSmpSuccess);
  287. // continue to the next sample
  288. listMeasuredSamples.Add (pSample.GetName());
  289. }
  290. // measurement completed
  291. m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.COMPLETED);
  292. // record end time
  293. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  294. ThreadOver();
  295. }
  296. //public bool DoReMeasure(List<Particle> particles, int imgscanspeed_index, int xrayscanmode_index, int scantime_count)
  297. //{
  298. // // got through measure list
  299. // foreach (var pSample in m_listMeasurableSamples)
  300. // {
  301. // // check and break if stop button is clicked
  302. // if (m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.STOPPED)
  303. // {
  304. // // stop button clicked
  305. // loger.Info("DoMeasure: stop button is clicked.");
  306. // // record end time
  307. // m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  308. // ThreadOver();
  309. // return false;
  310. // }
  311. // CSmplMeasure pSmplMeasure;
  312. // // create a sample measure object for the sample
  313. // switch (m_pProjData.m_nPackId)
  314. // {
  315. // case OTS_SysType_ID.IncA:
  316. // pSmplMeasure = new CSmplMeasureInclution(m_strWorkingFolder, pSample);
  317. // break;
  318. // case OTS_SysType_ID.CleannessA:
  319. // pSmplMeasure = new CSmplMeasureCleanliness(m_strWorkingFolder, pSample);
  320. // break;
  321. // default:
  322. // pSmplMeasure = new CSmplMeasureInclution(m_strWorkingFolder, pSample);
  323. // break;
  324. // }
  325. // // set measure thread
  326. // pSmplMeasure.SetMsrThread(this);
  327. // pSmplMeasure.DoMeasureForOneSample();
  328. // }
  329. // // measurement completed
  330. // m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.COMPLETED);
  331. // // record end time
  332. // m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  333. // ThreadOver();
  334. // return true;
  335. //}
  336. // hole preview
  337. public void DoHolePreview(int a_nHoleID, CDomain a_pMeasureArea)
  338. {
  339. // start measurement, creat thread measure status class, let the main thread know that measurement started
  340. // set measure status to in-process
  341. //record time
  342. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.START);
  343. DateTime timeStart = m_ThreadStatus.GetStartTime();
  344. ST_MSTMsg MsgMsrStart = new ST_MSTMsg();
  345. MsgMsrStart.iMsgType = ENUM_MSG_TYPE.MTHREADSTATUS;
  346. MsgMsrStart.STMThreadStu.iMsrStatu =OTS_MSR_THREAD_STATUS.INPROCESS;
  347. SendMessageToMeasureApp(MsgMsrStart);
  348. // connect hardware
  349. if (!m_SemController.Connect())
  350. {
  351. // failed to connect hardware
  352. SetMsrLoopStatus(otsdataconst.OTS_MSR_THREAD_STATUS.FAILED);
  353. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  354. ThreadOverWithoutDisConnect();
  355. }
  356. COTSSample pSampleHole = CreateHoleSample(a_pMeasureArea);
  357. // create a sample measure object for the sample
  358. CSmplMeasure pSmplMeasure = new CSmplMeasureCleanliness(m_strWorkingFolder,pSampleHole);
  359. // set measure thread
  360. pSmplMeasure.SetMsrThread(this);
  361. // update thread measure status class, let the main thread know that this sample measurement starts
  362. // set working folder string
  363. pSmplMeasure.SetSample(pSampleHole);
  364. pSmplMeasure.SetWorkingFolder(m_strWorkingFolder);
  365. // do measure
  366. pSmplMeasure.DoHolePreview(a_nHoleID);
  367. // check if measurement is successful
  368. if (pSampleHole.GetMsrStatus().GetStatus() == OTS_MSR_SAMPLE_STATUS.STOPPED)
  369. {
  370. // record end time
  371. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  372. // measurement stopped
  373. SetMsrLoopStatus(otsdataconst.OTS_MSR_THREAD_STATUS.STOPPED);
  374. // update thread measure status class, let the main thread know that this sample measurement stopped
  375. ST_MSTMsg MsgSmpStop = new ST_MSTMsg();
  376. MsgSmpStop.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  377. MsgSmpStop.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.STOPPED;
  378. SendMessageToMeasureApp(MsgSmpStop);
  379. ThreadOverWithoutDisConnect();
  380. return;
  381. }
  382. else if (pSampleHole.GetMsrStatus().GetStatus() == OTS_MSR_SAMPLE_STATUS.FAILED)
  383. {
  384. // measurement failed
  385. SetMsrLoopStatus(otsdataconst.OTS_MSR_THREAD_STATUS.FAILED);
  386. // record end time
  387. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  388. // update thread measure status class, let the main thread know that this sample measurement failed
  389. ST_MSTMsg MsgSmpFailed = new ST_MSTMsg();
  390. MsgSmpFailed.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  391. MsgSmpFailed.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.FAILED;
  392. SendMessageToMeasureApp(MsgSmpFailed);
  393. ThreadOverWithoutDisConnect();
  394. return;
  395. }
  396. // record end time
  397. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  398. // update thread measure status class, let the main thread know that this sample measurement successes
  399. ST_MSTMsg MsgSmpSuccess = new ST_MSTMsg();
  400. MsgSmpSuccess.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  401. MsgSmpSuccess.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.SUCCESSED;
  402. SendMessageToMeasureApp(MsgSmpSuccess);
  403. // measurement completed
  404. SetMsrLoopStatus(otsdataconst.OTS_MSR_THREAD_STATUS.COMPLETED);
  405. // record end time
  406. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  407. ThreadOverWithoutDisConnect();
  408. }
  409. public COTSSample CreateHoleSample(CDomain a_pMsrArea)
  410. {
  411. COTSSample pHoleSample = new COTSSample();
  412. pHoleSample.SetMsrArea(a_pMsrArea);
  413. // get min magnification
  414. CSEMStageData pSEMStageData = m_pProjData.GetSEMStageData();
  415. double dMinMag = pSEMStageData.GetMinMag();
  416. // get scan field size 100
  417. int nScanFieldSize100 = pSEMStageData.GetScanFieldSize100();
  418. // get working distance
  419. double dWorkingDistance = 0.0;
  420. if (!GetSEMWorkingDistanceFromHW(ref dWorkingDistance))
  421. {
  422. return null;
  423. }
  424. CSEMDataMsr poSEMDataMsr = new CSEMDataMsr();
  425. poSEMDataMsr.SetScanFieldSize100(nScanFieldSize100);
  426. poSEMDataMsr.SetWorkingDistance(dWorkingDistance);
  427. poSEMDataMsr.SetMagnification(dMinMag);
  428. pHoleSample.SetSEMDataMsr(poSEMDataMsr);
  429. // Set image scan param
  430. COTSImgScanPrm poImageScanParam = new COTSImgScanPrm();
  431. poImageScanParam.SetStopMode(((int)OTS_MEASURE_STOP_MODE.CoverMode).ToString());
  432. poImageScanParam.SetStartImageMode(OTS_GET_IMAGE_MODE.FROM_CENTER);
  433. poImageScanParam.SetScanImageSpeed(OTS_IMAGE_SCANSPEED_OPTIONS.low);
  434. //poImageScanParam.SetImagePixelSize(OTS_FIVE_TIES_OPTIONS.TIE1);
  435. CSampleParam poMsrParams = pHoleSample.GetMsrParams();
  436. poImageScanParam.SetImageResulotion(GetListMeasurableSamples()[0].GetMsrParams().GetImageScanParam().GetImageResulotion());//由于各样品分辨率应该一致,故此处没有读取选取的特定样品孔样品
  437. poMsrParams.SetImageScanParam(poImageScanParam);
  438. pHoleSample.SetMsrParams(poMsrParams);
  439. return pHoleSample;
  440. }
  441. public bool GetSEMWorkingDistanceFromHW(ref double a_dWorkingDistance)
  442. {
  443. m_SemController.GetWorkingDistance(ref a_dWorkingDistance);
  444. return true;
  445. }
  446. // measure status
  447. public void SetMsrLoopStatus(otsdataconst.OTS_MSR_THREAD_STATUS a_nMsrLoopStatus)
  448. {
  449. m_ThreadStatus.SetStatus( a_nMsrLoopStatus);
  450. }
  451. }
  452. }