| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360 | //时间:20200610//作者:郝爽//功能:测量线程using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;using System.Threading;using System.IO;using System.Drawing;using System.Xml;using SmartSEMControl;using MeasureData;using FileManager;using WebManager;using OpenCvSharp;using DBManager;using Extender;using CookComputing.XmlRpc;namespace MeasureThread{    #region 信息定义    public delegate void ThreadStatusHandler(object sender, ThreadStatusEventArgs e);  //声明委托    public delegate void CutHolesStatusHandler(object sender, CutHolesStatusEventArgs e);    //测量线程状态    public class ThreadStatusEventArgs    {        //状态        public Boolean State        {            get { return m_state; }            set { m_state = value; }        }        private Boolean m_state;        //时间        public DateTime Time        {            get { return m_time; }            set { m_time = value; }        }        private DateTime m_time;        //步骤代码        public String Step_Code        {            get { return step_Code; }            set { step_Code = value; }        }        private String step_Code;        //其他消息        public String Message        {            get { return this.message; }            set { this.message = value; }        }        private String message;        //孔名        public String HoleName        {            get { return this.holeName; }            set { this.holeName = value; }        }        private String holeName;        //图片信息        public class PictureInformation        {            public String Picture_FullPath            {                get { return picture_FullPath; }                set { picture_FullPath = value; }            }            private String picture_FullPath;            public double Work_Voltage            {                get { return work_Voltage; }                set { work_Voltage = value; }            }            private double work_Voltage;            public double Magnification            {                get { return magnification; }                set { magnification = value; }            }            private double magnification;            public double Work_Distance            {                get { return work_Distance; }                set { work_Distance = value; }            }            private double work_Distance;            public String Work_Status            {                get { return work_Status; }                set { work_Status = value; }            }            private String work_Status;        }        //图片信息实例类        public PictureInformation Picture_Information        {            get { return picture_Information; }            set { picture_Information = value; }        }        private PictureInformation picture_Information;        //图像处理信息        public class ImageInformation        {            public int Method_Name            {                get { return method_Name; }                set { method_Name = value; }            }            private int method_Name;            public Source_Img_Degree_Direction SIDD;            public Cut_Position CP;            public Cut_Success CS;            public Trapezoid_Top_Center_Position TTCP;            public Auto_Foucs AF;            public Auto_Stigmatic AS;            public Center_Position_OffsetAngle_Direction CPOD;            public Measure_Size MS;            public ImageInformation()            {                SIDD = new Source_Img_Degree_Direction();                CP = new Cut_Position();                CS = new Cut_Success();                TTCP = new Trapezoid_Top_Center_Position();                AF = new Auto_Foucs();                AS = new Auto_Stigmatic();                CPOD = new Center_Position_OffsetAngle_Direction();                MS = new Measure_Size();            }            //1-计算原始图像偏移角度及方向            public class Source_Img_Degree_Direction            {                public Boolean Is_Image = false;                public double Degree                {                    get { return degree; }                    set { degree = value; }                }                private double degree;                public int Direction                {                    get { return direction; }                    set { direction = value; }                }                private int direction;                public int State                {                    get { return state; }                    set { state = value; }                }                private int state;            }            //2-计算切割点位置            public class Cut_Position            {                public Boolean Is_Image = false;                public double Offsetx                {                    get { return offsetx; }                    set { offsetx = value; }                }                private double offsetx;                public double Offsety                {                    get { return offsety; }                    set { offsety = value; }                }                private double offsety;                public int State                {                    get { return state; }                    set { state = value; }                }                private int state;            }            //3-是否切割成功            public class Cut_Success            {                public Boolean Is_Image = false;                public int State                {                    get { return state; }                    set { state = value; }                }                private int state;            }            //4-计算切割后图像梯形区域上边中心点坐标            public class Trapezoid_Top_Center_Position            {                public Boolean Is_Image = false;                public double TopCenterX                {                    get { return topCenterX; }                    set { topCenterX = value; }                }                private double topCenterX;                public double TopCenterY                {                    get { return topCenterY; }                    set { topCenterY = value; }                }                private double topCenterY;                public int State                {                    get { return state; }                    set { state = value; }                }                private int state;            }            //5-自动对焦            public class Auto_Foucs            {                public Boolean Is_Image = true;                public String Img_Path                {                    get { return img_Path; }                    set { img_Path = value; }                }                private String img_Path;            }            //6-自动像闪            public class Auto_Stigmatic            {                public Boolean Is_Image = true;                public String Img_Path                {                    get { return img_Path; }                    set { img_Path = value; }                }                private String img_Path;            }            //7-计算切割面区域中心坐标,以及偏移角度及方向            public class Center_Position_OffsetAngle_Direction            {                public Boolean Is_Image = false;                public double CenterX                {                    get { return centerX; }                    set { centerX = value; }                }                private double centerX;                public double CenterY                {                    get { return centerY; }                    set { centerY = value; }                }                private double centerY;                public double Degree                {                    get { return degree; }                    set { degree = value; }                }                private double degree;                public int Direction                {                    get { return direction; }                    set { direction = value; }                }                private int direction;                public int State                {                    get { return state; }                    set { state = value; }                }                private int state;            }            //8-测量尺寸            public class Measure_Size            {                public Boolean Is_Image = false;                public int State                {                    get { return state; }                    set { state = value; }                }                private int state;            }        }        //图像处理信息实例类        public ImageInformation Image_Information        {            get { return image_Information; }            set { image_Information = value; }        }        private ImageInformation image_Information;        public ThreadStatusEventArgs(string a_State)        {            picture_Information = new PictureInformation();            image_Information = new ImageInformation();        }    }    //切孔状态    public class CutHolesStatusEventArgs    {        public string State        {            get { return m_state; }            set { m_state = value; }        }        private string m_state;        public string HoleName        {            get { return m_holeName; }            set { m_holeName = value; }        }        private string m_holeName;        public CutHolesStatusEventArgs(string a_state, string a_holeName)        {            this.m_state = a_state;            this.m_holeName = a_holeName;        }    }    #endregion    public class Measure    {        NLog.Logger log;        #region 变量定义        //Web接口类        public ImageProcess ImagePro = null;        //SmartSEM远程路径        public String RemoteELYPath = "";        public String RemoteMLFPath = "";        //扫描周期        private float cycle_time = 0;        //人工干预        public int hand_intervene = 2;        //样品台保护值        public float X_Min = 0;        public float X_Max = 0.13f;        public float Y_Min = 0;        public float Y_Max = 0.13f;        public float Z_Min = 0;        public float Z_Max = 0.05f;        public float T_Min = -4;        public float T_Max = 70;        public float R_Min = -380;        public float R_Max = 380;        public float M_Min = 0;        public float M_Max = 0.012f;        public event ThreadStatusHandler SendThreadStatus;  // 声明事件        public event CutHolesStatusHandler SendCutHolesStatus;  // 声明事件        //定义一个全局的消息类        ThreadStatusEventArgs arg = new ThreadStatusEventArgs("0-0");        //全局只有一个fatorySEM        static FactoryHardware factorySEM = FactoryHardware.Instance;        ISEMControl iSEM = factorySEM.ISEM;        //@的作用是不用转义字符\\只打一个就行        const String ImageName0 = @"SEMStraighten.tif"; //传给客户,原始图像,为拉直操作        const String ImageName1 = @"FIBStraighten.tif"; //传给客户,原始图像,为拉直操作        //const String ImageName1 = @"SEMFindCutPostion.tif"; //传给客户,作水平校正        const String ImageName2 = @"FIBCutPostion.tif";//传给客户,找到切割点        const String ImageName31 = @"FIBBefore.tif";        const String ImageName32 = @"FIBAfter.tif";        const String ImageName4 = @"SEMTrapCP.tif";//传给客户,找到已经切割点        const String ImageName5 = @"SEMDegreeTrap.tif";//传给客户,水平校正        const String ImageName6 = @"SEMMagEnd.tif";//传给客户,测量层高        const String ImageName7 = @"EDSImage.tif";//计算感兴趣的区域        const String ImageName8 = @"SEMAfterMoveToPix.tif";//精确的位置移动后的图像        const String ImageName9 = @"SEMBeforeMoveToPix.tif";//精确的位置移动后的图像        const String ImageName10 = @"SEMTrapCPAfter.tif";//传给客户,找到已经切割点        const String ImageName111 = @"SEMBeforeCut.tif";//切割前SEM拍照        const String ImageName112 = @"SEMAfterCut.tif";//切割后SEM拍照        const String ImageNameTwo_1 = @"SEMRegion.tif";//第一个测量区域拍照        const String ImageNameTwo_2 = @"SEMTwoRegion.tif";//第二个测量区域拍照        const String ImageNameTwo_11 = @"SEMOneRegionMove.tif";//第一个测量区域拍照        const String ImageNameTwo_22 = @"SEMTwoRegionMove.tif";//第二个测量区域拍照        const String MacoInsertPt = "GIS Insert.MLF"; //传入PT针        const String MacoRetractPt = "GIS Retract.MLF"; //退出PT针        const String MacoScanPic = "Scan picture.MLF";//一般质量抓图的宏        const String MacoGoodPic = "Good picture.MLF";//高质量抓图的宏        const String MacoExportTif = "Export TIFF.MLF";// 导出有标尺的图像,这个图像为使用工具SmartSEM工具的图像        const String ElyDeposition = @"Deposition.ely"; //沉积        const String ElyCrossSection = @"CrossSection.ely"; //切割        const float fMin = (float)0.0000002; //单位是米        const float fSateyZ = (float)0.007;//单位是米        public Boolean key_stop = false;        String focus_path = "";        String FIBfocus_path = "";        String StigX_path = "";        String StigY_path = "";        String EDS_path = "";        String data_path = "";        int m_nWorkHoleNo = -1;        //测量文件        private MeasureFile m_measureFile;        public MeasureFile MeasureFile        {            get { return this.m_measureFile; }            set { this.m_measureFile = value; }        }        //测量的切割孔,这个切孔的状态要保存的测量文件中去        private List<MeasureData.CutHole> m_cutHoles;        public List<MeasureData.CutHole> cutHoles        {            get { return this.m_cutHoles; }            set { this.m_cutHoles = value; }        }        public MeasureParam MParam//测量参数对象        {            get { return this.m_measureFile.MParam; }            //set { this.m_measureParam = value; }        }        //工作文件夹        private string m_WorkingFolder;        public string WorkingFolder        {            get { return this.m_WorkingFolder; }            set { this.m_WorkingFolder = value; }        }        //程序当前路径        private string m_ProgramFolder = Directory.GetCurrentDirectory();        //线程状态        private ThreadStatus m_ThreadStatus;        public ThreadStatus TStatus        {            get { return this.m_ThreadStatus; }            set { this.m_ThreadStatus = value; }        }        #endregion        //构造函数        public Measure(String webServerIP, String webServerPort, String webServerUrl)        {            log = NLog.LogManager.GetCurrentClassLogger();            TStatus = new ThreadStatus();            cutHoles = new List<MeasureData.CutHole>();            //配置远程连接            ImagePro = new ImageProcess(webServerIP, webServerPort, webServerUrl);        }        //初始化测量业务, 读测量文件,判断是否有可测试的切孔        public bool InitMeas(MeasureFile a_measureFile)        {            log.Info("进入初始化函数");            m_measureFile = a_measureFile;            List<CutHole> listHoles = m_measureFile.ListCutHole;            foreach (CutHole h in listHoles)            {                if (h.SWITCH == true)                {                    m_cutHoles.Add(h);                }            }            if (m_cutHoles.Count == 0)                return false;            if (MParam.EDS == true)            {                log.Info("进行能谱分析,初始化Xray数据库", true);                Init_MeasDB();            }            return true;        }        //给前台UI发送消息步骤        public void SendMsg(string step_code)        {            arg.Step_Code = step_code;            arg.Time = DateTime.Now;            SendThreadStatus(this, arg);        }        //给前台UI发送孔状态信息        public void SendCutHoleMsg(string a_state, string a_holeName)        {            CutHolesStatusEventArgs arg = new CutHolesStatusEventArgs(a_state, a_holeName);            arg.HoleName = a_holeName;            arg.State = a_state;            SendCutHolesStatus(this, arg);        }        //测量流程        public void DoMeasure()        {            //创建线程的测量状态的更新            this.TStatus.ComputeTime(THREAD_TIME_TYPE.START);            //检查硬件连接是否正常            log.Warn("测量线程:开始连接硬件...", true);            if (!ConnectHardware())            {                MessageBox.Show("连接电镜失败!", "重要错误", MessageBoxButtons.OK, MessageBoxIcon.Error);                this.TStatus.ComputeTime(THREAD_TIME_TYPE.STOPPED);                log.Error("测量线程报错:连接硬件硬件连接失败", false);                return;            }            //设置工作文件夹            SetWorkingFolderStr();            //设置SmartSEM远程路径            iSEM.SetRemoteELYPath(RemoteELYPath);            iSEM.SetRemoteMLFPath(RemoteMLFPath);            //增加EDS控制            //将停止键复位            key_stop = false;            //开始测量就将模式设置为SEM            log.Info("测量线程:开始切换到SEM模式", true);            if (!iSEM.CmdFIBModeSEM())            {                log.Error("测量线程报错:开始切换到SEM模式失败。", false);                return;            }            arg.Picture_Information.Work_Status = "SEM";            //设置扫描周期            log.Info("测量线程:设置电镜图像扫描周期为对焦接口程序适合的扫描周期", true);            iSEM.CmdFocusScanSpeed(MParam.ScanSpeedNormal);//CmdFocusRate(4);            Thread.Sleep(200);            cycle_time = iSEM.GetCycleTime();            if (cycle_time == 0)            {                log.Error("测量线程报错:获取扫描周期时间失败", false);                return;            }            Thread.Sleep((int)cycle_time + 100);            //开始做各个孔的检测            for (int i = 0; i < m_cutHoles.Count; i++)            {                //自动亮度对比度                log.Info("测量线程:开启自动亮度,对比度调节", true);                iSEM.SetAutoBright(100);                Thread.Sleep(200);                iSEM.SetAutoContrast(100);                Thread.Sleep(200);                //log.Info("SEM模式设置自动亮度调节目标50%,亮度调节目标30%", true);                if (!iSEM.SetAutoVideoBrightnessAndContrast())                {                    log.Error("测量线程报错:开始设置自动亮度、对比度失败。", false);                    return;                }                Thread.Sleep(5000);                log.Warn("测量线程:测试第" + i.ToString() + "个分析点。", true);                //记录测量序号和孔名                m_nWorkHoleNo = i;                arg.HoleName = m_cutHoles[i].HoleName;                //最终数据存放目录                data_path = WorkingFolder + "\\" + m_cutHoles[i].HoleName;                //对焦数据存放目录                focus_path = WorkingFolder + "\\" + m_cutHoles[i].HoleName + "\\Focus";                MParam.AutoFocus.Path = focus_path;                if (!Directory.Exists(focus_path))                {                    Directory.CreateDirectory(focus_path);                }                //StigX数据存放目录                StigX_path = WorkingFolder + "\\" + m_cutHoles[i].HoleName + "\\StigX";                MParam.AutoStigX.Path = StigX_path;                if (!Directory.Exists(StigX_path))                {                    Directory.CreateDirectory(StigX_path);                }                //StigY数据存放目录                StigY_path = WorkingFolder + "\\" + m_cutHoles[i].HoleName + "\\StigY";                MParam.AutoStigY.Path = StigY_path;                if (!Directory.Exists(StigY_path))                {                    Directory.CreateDirectory(StigY_path);                }                //EDS数据存放路径                if (MParam.EDS == true)                {                    EDS_path = WorkingFolder + "\\" + m_cutHoles[i].HoleName + "\\EDS";                    MParam.EDSParam.Path = EDS_path;                    if (!Directory.Exists(EDS_path))                    {                        Directory.CreateDirectory(EDS_path);                    }                }                //判断孔状态                if (m_cutHoles[i].STATE != State.Ready)                {                    log.Warn("测试孔" + m_cutHoles[i].HoleName + "状态非就绪,不予测量。", true);                    continue;                }                //20201127增加Scanrotate Off                iSEM.SetScanRotationOff();                Thread.Sleep(200);                //20.光束等复位                iSEM.SetBeamShiftX(0);                Thread.Sleep(200);                iSEM.SetBeamShiftY(0);                Thread.Sleep(200);                //开始循环工作                if (i == 0)                {                    log.Warn("测量线程:分析点" + m_cutHoles[i].HoleName + "开始测量。", true);                    m_cutHoles[i].START = DateTime.Now;                    //切孔操作-开始                    m_cutHoles[i].STATE = State.InProcess;                    SendCutHoleMsg(((int)m_cutHoles[i].STATE).ToString(), m_cutHoles[i].HoleName);                    log.Warn("测量线程:控制样品台至样品分析点位置(R,X,Y,Z) = (" + m_cutHoles[0].Position.R.ToString() + ","                        + m_cutHoles[0].Position.X.ToString() + ","                        + m_cutHoles[0].Position.Y.ToString() + ","                        + m_cutHoles[0].Position.Z.ToString() + ")", true);                    #region 坐标恢复                    //0、先移动Z轴到比较低的位置上。                    if (MParam.Tilt)//如果是倾斜样品台,移动Z轴                    {                        Locate lo = new Locate(iSEM);                        if (!lo.MoveZAxis(fSateyZ, Locate.ZAxisDirection.down))                        {                            arg.State = false;                            arg.Message = "样品台移动到观测点:" + m_cutHoles[i] + "的位置失败。";                            SendMsg("0-0");                            log.Error("测量线程报错:样品台Z轴移动失败,Z为" + fSateyZ.ToString(), false);                            m_cutHoles[i].STATE = State.Failed;                            m_cutHoles[i].END = DateTime.Now;                            m_measureFile.Save();                            SendCutHoleMsg(((int)m_cutHoles[i].STATE).ToString(), m_cutHoles[i].HoleName);                            Thread.Sleep(3000);                            continue;                        }                        while (true)                        {                            Thread.Sleep(4000);                            if (iSEM.GetStageIs() == 0)                            {                                break;                            }                        }                        //判断是否停止进程                        if (key_stop)                        {                            m_cutHoles[i].STATE = State.Failed;                            m_cutHoles[i].END = DateTime.Now;                            m_measureFile.Save();                            SendCutHoleMsg(((int)m_cutHoles[i].STATE).ToString(), m_cutHoles[i].HoleName);                            log.Info("停止键被按下", true);                            return;                        }                    }                    //1、移动样品台到第一个观测点,先移动R轴,再移动XY轴                    if (!iSEM.SetStageGotoR(m_cutHoles[0].Position.R))                    {                        arg.State = false;                        arg.Message = "样品台移动到观测点:" + m_cutHoles[i] + "的位置失败。";                        SendMsg("0-0");                        log.Error("测量线程报错:样品台R轴移动失败,R为" + m_cutHoles[0].Position.ToString(), false);                        m_cutHoles[i].STATE = State.Failed;                        m_cutHoles[i].END = DateTime.Now;                        m_measureFile.Save();                        SendCutHoleMsg(((int)m_cutHoles[i].STATE).ToString(), m_cutHoles[i].HoleName);                        Thread.Sleep(3000);                        continue;                    }                    while (true)                    {                        Thread.Sleep(4000);                        if (iSEM.GetStageIs() == 0)                        {                            break;                        }                    }                    //判断是否停止进程                    if (key_stop)                    {                        m_cutHoles[i].STATE = State.Failed;                        m_cutHoles[i].END = DateTime.Now;                        m_measureFile.Save();                        SendCutHoleMsg(((int)m_cutHoles[i].STATE).ToString(), m_cutHoles[i].HoleName);                        log.Info("停止键被按下", true);                        return;                    }                    //2、移动XY轴                    if (!iSEM.MoveStageXY(m_cutHoles[0].Position.X, m_cutHoles[0].Position.Y))                    {                        arg.State = false;                        arg.Message = "样品台移动到观测点:" + m_cutHoles[i] + "的位置失败。";                        SendMsg("0-0");                        log.Error("测量线程报错:样品台XY轴移动失败,(X,Y)为"                            + m_cutHoles[0].Position.X.ToString() + ","                            + m_cutHoles[0].Position.Y.ToString() + ")", false);                        m_cutHoles[i].STATE = State.Failed;                        m_cutHoles[i].END = DateTime.Now;                        m_measureFile.Save();                        SendCutHoleMsg(((int)m_cutHoles[i].STATE).ToString(), m_cutHoles[i].HoleName);                        Thread.Sleep(3000);                        continue;                    }                    while (true)                    {                        Thread.Sleep(4000);                        if (iSEM.GetStageIs() == 0)                        {                            break;                        }                    }                    //判断是否停止进程                    if (key_stop)                    {                        m_cutHoles[i].STATE = State.Failed;                        m_cutHoles[i].END = DateTime.Now;                        m_measureFile.Save();                        SendCutHoleMsg(((int)m_cutHoles[i].STATE).ToString(), m_cutHoles[i].HoleName);                        log.Info("停止键被按下", true);                        return;                    }                    //3、恢复Z轴                    if (MParam.Tilt)                    {                        //恢复Z轴                                            if (!iSEM.SetStageGotoZ(m_cutHoles[0].Position.Z))                        {                            arg.State = false;                            arg.Message = "样品台移动到观测点:" + m_cutHoles[i] + "的位置失败。";                            SendMsg("0-0");                            log.Error("测量线程报错:样品台Z轴移动失败,Z为" + m_cutHoles[0].Position.Z.ToString(), false);                            m_cutHoles[i].STATE = State.Failed;                            m_cutHoles[i].END = DateTime.Now;                            m_measureFile.Save();                            SendCutHoleMsg(((int)m_cutHoles[i].STATE).ToString(), m_cutHoles[i].HoleName);                            Thread.Sleep(3000);                            continue;                        }                        while (true)                        {                            Thread.Sleep(4000);                            if (iSEM.GetStageIs() == 0)                            {                                break;                            }                        }                        //判断是否停止进程                        if (key_stop)                        {                            log.Info("停止键按下。", true);                            m_cutHoles[i].STATE = State.Failed;                            m_cutHoles[i].END = DateTime.Now;                            m_measureFile.Save();                            SendCutHoleMsg(((int)m_cutHoles[i].STATE).ToString(), m_cutHoles[i].HoleName);                            return;                        }                    }                    arg.State = true;                    arg.Message = "样品台移动到观测点:" + m_cutHoles[i] + "的位置成功。";                    SendMsg("0-0");                    //4、设置WD                    iSEM.SetWorkingDistance(m_measureFile.ListCutHole[m_nWorkHoleNo].Position.WD);                    Thread.Sleep(1000);                    #endregion                    //第一个点开始测量                    if (FirstHole())                    {                        //保存文件,将测量状态更改                        m_cutHoles[i].STATE = State.Success;                        m_cutHoles[i].END = DateTime.Now;                        m_measureFile.Save();                        SendCutHoleMsg(((int)m_cutHoles[i].STATE).ToString(), m_cutHoles[i].HoleName);                    }                    //失败                    else                    {                        m_cutHoles[i].STATE = State.Failed;                        m_cutHoles[i].END = DateTime.Now;                        m_measureFile.Save();                        SendCutHoleMsg(((int)m_cutHoles[i].STATE).ToString(), m_cutHoles[i].HoleName);                    }                }                else                {                    //其他孔的测量                    log.Info("测量线程:分析点" + m_cutHoles[i].HoleName + "开始测量。", true);                    m_cutHoles[i].START = DateTime.Now;                    m_cutHoles[i].STATE = State.InProcess;                    SendCutHoleMsg(((int)m_cutHoles[i].STATE).ToString(), m_cutHoles[i].HoleName);                    //其他孔测量之前的初始化                    if (!OtherHole_Init())                    {                        arg.State = false;                        arg.Message = "样品台移动到观测点:" + m_cutHoles[i] + "的位置失败。";                        SendMsg("0-0");                        Thread.Sleep(3000);                        log.Info("测量线程:" + arg.Message, true);                        continue;                    }                    arg.State = true;                    arg.Message = "样品台移动到观测点:" + m_cutHoles[i] + "的位置成功。";                    SendMsg("0-0");                    //其他孔开始测量                    if (OtherHole())                    {                        //保存文件,将测量状态更改                        m_cutHoles[i].STATE = State.Success;                        m_cutHoles[i].END = DateTime.Now;                        m_measureFile.Save();                        SendCutHoleMsg(((int)m_cutHoles[i].STATE).ToString(), m_cutHoles[i].HoleName);                    }                    //失败                    else                    {                        m_cutHoles[i].STATE = State.Failed;                        m_cutHoles[i].END = DateTime.Now;                        m_measureFile.Save();                        SendCutHoleMsg(((int)m_cutHoles[i].STATE).ToString(), m_cutHoles[i].HoleName);                    }                }                if (key_stop)                {                    m_cutHoles[i].END = DateTime.Now;                    m_cutHoles[i].STATE = State.Ready;                    m_measureFile.Save();                    SendCutHoleMsg(((int)m_cutHoles[i].STATE).ToString(), m_cutHoles[i].HoleName);                    arg.Message = "用户停止测量";                    SendMsg("0-0");                    break;                }                //两个点之间更换,加延时以便完成显示                Thread.Sleep(3000);            }        }        //检查硬件连接是否正常        public bool ConnectHardware()        {            //返回硬件的连接状态            return iSEM.ConnectStatus();        }        //设置工作文件夹        public bool SetWorkingFolderStr()        {            WorkingFolder = m_measureFile.FilePath;            return true;        }        //插入PT针        public bool InsertPT()        {            string fn = m_ProgramFolder + "\\Macro\\" + MacoInsertPt;            //SendMsg("调用宏插入PT针宏文件" + fn);            iSEM.CMDMCFFilename(fn);            //延时1s??            Thread.Sleep(1000);            return true;        }        //撤出PT针        public bool RetractPT()        {            string fn = m_ProgramFolder + "\\Macro\\" + MacoRetractPt;            //SendMsg("调用宏撤出PT针宏文件" + fn);            iSEM.CMDMCFFilename(fn);            //延时1s??            Thread.Sleep(1000);            return true;        }        //PT沉积        public bool PTWork()        {            //执行PT沉积的ELY文件            if (!ExcuteEly(MParam.PTTemp))            {                return false;            }            //等待沉积完成            while (true)            {                Thread.Sleep(7000);                if (iSEM.GetFIBMode() == 0)                {                    break;                }            }            return true;        }        //FIB切割        public bool FIBWork()        {            //执行PT沉积的ELY文件            if (!ExcuteEly(MParam.FIBTemp))            {                return false;            }            //等待切割完成            while (true)            {                Thread.Sleep(10000);                if (iSEM.GetFIBMode() == 0)                {                    break;                }            }            return true;        }        //执行ELY文件的步骤        public bool ExcuteEly(string a_filename)        {            //执行ELy文件有三个动作            //1. 选择ELY文件            //SendMsg("选择ELY文件");            if (!iSEM.CmdFIBLoadELY(a_filename))            {                //SendMsg("选择ELY文件失败");                return false;            }            Thread.Sleep(1000);            //2. 确认ELY文件            //SendMsg("确认ELY文件");            if (!iSEM.CmdFIBEXPOSUREELY())            {                //SendMsg("确认ELY文件失败");                return false;            }            Thread.Sleep(1000);            //3. 执行ELY文件            //SendMsg("执行ELY文件");            if (!iSEM.CmdFIBSTARTELY())            {                //SendMsg("执行ELY文件失败");                return false;            }            Thread.Sleep(1000);            return true;        }        /// <summary>        ///13. 自动 定位功能,沉积        /// </summary>        /// <returns></returns>        public bool GetPoistion()        {            float x0 = 0, y0 = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0, px = 0;            int state = 1;            log.Info("测量线程:13.自动定位、沉积-功能自动定位电压" + MParam.Location_Voltage.ToString() + "自动定位放大倍数" + MParam.Location_Magnification.ToString(), true);            Thread.Sleep(200);            //1.控制SEM放大600X            if (!iSEM.SetSEMVoltage(MParam.Location_Voltage))            {                arg.Message = "电压设置" + MParam.Location_Voltage.ToString("0.0") + "失败";                arg.State = false;                SendMsg("2-0");                log.Error("测量线程报错:13.自动定位、沉积-自动定位电压" + MParam.Location_Voltage.ToString() + "控制失败", false);                return false;            }            Thread.Sleep(200);            if (!iSEM.SetMagnification(MParam.Location_Magnification))            {                arg.Message = "放大" + MParam.Location_Magnification.ToString("0.0") + "倍失败";                arg.State = false;                SendMsg("2-0");                log.Error("测量线程报错:13.自动定位、沉积-自动定位放大倍数" + MParam.Location_Magnification.ToString() + "控制失败", false);                return false;            }            float current = iSEM.GetMagnification();            while (Math.Abs(current - MParam.Location_Magnification) > 1)            {                iSEM.SetMagnification(MParam.Location_Magnification);                Thread.Sleep(200);                current = iSEM.GetMagnification();            }            arg.State = true;            arg.Message = "放大" + MParam.Location_Magnification.ToString("0.0") + "倍成功";            SendMsg("2-0");            //判断是否停止进程            if (key_stop)            {                log.Info("停止键按下。", true);                return false;            }            //判断是否为仅拍照,不是则执行FIB操作            if (!MParam.Is_Photograph)            {                log.Info("测量线程:切换到FIB模式。", true);                //6.设置FIB拍照参数——扫描时间、束流等                //7.控制FIB自动亮度、对比度                Thread.Sleep(200);                if (!iSEM.CmdFIBModeFIB())                {                    arg.Message = "FIB模式切换失败";                    arg.State = false;                    SendMsg("2-1");                    log.Error("测量线程报错:切换到FIB模式失败。", false);                    return false;                }                arg.State = true;                arg.Picture_Information.Work_Status = "FIB";                arg.Message = "FIB模式切换成功";                SendMsg("2-1");                Thread.Sleep(1000);                //判断是否停止进程                if (key_stop)                {                    log.Info("停止键按下。", true);                    return false;                }                //8.控制FIB拍照                //9.保存照片======更改路径                //20201103,FIB使用定位的放大倍数                String fileName2 = data_path + "\\" + m_cutHoles[m_nWorkHoleNo].HoleName + "_" + MParam.Location_Magnification.ToString("0") + "_" + ImageName2;                arg.Picture_Information.Picture_FullPath = fileName2;                arg.Picture_Information.Work_Voltage = iSEM.GetSEMVoltage();                Thread.Sleep(200);                arg.Picture_Information.Magnification = iSEM.GetMagnification();                Thread.Sleep(200);                arg.Picture_Information.Work_Distance = iSEM.GetWorkingDistance();                Thread.Sleep(200);                //FIB的放大位数,将来会改                log.Info("测量线程:设置FIB放大倍数" + MParam.Location_Magnification.ToString(), true);                //20201103,FIB使用定位的放大倍数                if (!iSEM.SetFIBMagnification(MParam.Location_Magnification))                {                    arg.Message = "FIB放大倍数设置失败";                    arg.State = false;                    SendMsg("2-2");                    log.Error("测量线程失败:FIB放大倍数设置失败。", false);                    return false;                }                arg.Message = "FIB放大倍数设置成功";                arg.State = true;                SendMsg("2-2");                Thread.Sleep(200);                //判断是否停止进程                if (key_stop)                {                    log.Info("停止键按下。", true);                    return false;                }                //4、设置WD                iSEM.SetWorkingDistance(m_measureFile.ListCutHole[m_nWorkHoleNo].Position.WD);                Thread.Sleep(1000);                //20201127增加自动亮度对比度                if (MParam.FIBDo)                {                    if (MParam.FIBAutoBC)                    {                        //add by sun 2020-12-17 解决3大类样品FIB下亮度过白导致无法识别问题                        float m_TempBrightness = 50.0f;                        float m_TempContrast = 30.0f;                        if (MParam.SampleName == "3" || MParam.SampleName == "1")                        {                            m_TempBrightness = 50.0f;                            m_TempContrast = 30.0f;                            iSEM.SetAutoVideoOff();                            Thread.Sleep(200);                            iSEM.SetBrightness(m_TempBrightness); //50.0f                            Thread.Sleep(200);                            iSEM.SetContrast(m_TempContrast); //30.0f                            Thread.Sleep(200);                        }                        else //add by sun 2020-12-17 解决3大类样品FIB下亮度过白导致无法识别问题  end                        {                            iSEM.SetAutoVideoBrightnessAndContrast();                            //20201128陈工建议增加                            Thread.Sleep(200);                            iSEM.SetAutoBright(100);                            Thread.Sleep(200);                            iSEM.SetAutoContrast(100);                            Thread.Sleep(5000);                        }                    }                    else                    {                        iSEM.SetAutoVideoOff();                        Thread.Sleep(200);                        iSEM.SetBrightness(MParam.FIBB);                        Thread.Sleep(200);                        iSEM.SetContrast(MParam.FIBC);                        Thread.Sleep(200);                    }                }                //拍照前改变速度,延时                iSEM.CloseReduced();                Thread.Sleep(200);                //add by sun 2020-12-15 增加不同样品扫描速度参数,每大类样品3种扫描速度                iSEM.CmdFocusScanSpeed(MParam.ScanSpeedHigh);//iSEM.CmdSaveRate();                //add by sun 2020 - 12 - 15 增加不同样品扫描速度参数,每大类样品3种扫描速度 end                Thread.Sleep(200);                cycle_time = iSEM.GetCycleTime();                Thread.Sleep(Convert.ToInt32(cycle_time) + 100);                if (!GetImage(fileName2))                {                    arg.Message = "FIB拍照失败";                    arg.State = false;                    SendMsg("2-3");                    log.Error("测量线程报错:FIB拍照失败。", false);                    return false;                }                arg.State = true;                arg.Picture_Information.Picture_FullPath = fileName2;                arg.Message = "FIB拍照成功";                SendMsg("2-3");                Thread.Sleep(200);                //SendMsg("1-16");                iSEM.CmdFocusScanSpeed(MParam.ScanSpeedNormal);//CmdFocusRate(4);                Thread.Sleep(200);                cycle_time = iSEM.GetCycleTime();                Thread.Sleep(Convert.ToInt32(cycle_time) + 100);                //判断是否停止进程                if (key_stop)                {                    log.Info("停止键按下。", true);                    return false;                }                iSEM.CmdFIBModeSEM();                Thread.Sleep(200);                //10.将照片传给客户,返回梯形位置坐标,及样品类型参数(是否需要PT沉积,PT坐标位置,PT宽度、PT高度、梯形上、下边及深度、扫描时间、束流、样品放大倍数1、样品放大倍数2等切割参数)                log.Info("测量线程:调用图像处理接口,准备移动样品台", true);                log.Info("文件名=" + fileName2, true);                log.Info("样品类型=" + MParam.SampleName, true);                log.Info("供应商名称=" + MParam.Firm, true);                ImagePro.Img_Cut_Position(fileName2, Convert.ToInt32(MParam.SampleName), MParam.Firm, out x1, out y1, out x2, out y2, out state);                log.Info("FIB梯形左上角和右上角位置信息= (" + x1.ToString() + ", " + y1.ToString() + "), (" + x2.ToString() + ", " + y2.ToString() + ")", true);                log.Info("准备移动样品台返回状态=" + state.ToString(), true);                if (state == 1)                {                    //20201128将移动光束改为移动ely文件中的参数来实现沉积和切割                    float xc = (x1 + x2) / 2;                    float yc = (y1 + y2) / 2;                    x0 = xc - 512;                    y0 = 384 - yc;                    log.Info("移动像素 x = " + x0.ToString() + ",y=" + y0.ToString(), true);                    px = iSEM.GetPixelSize();                    //修改FIB切割的ELY文件坐标                    XmlDocument xmlDoc = new XmlDocument();                    xmlDoc.Load(MParam.FIBTemp);//加载baixml文件,xmlpath 为XML文件的路径du                    XmlNode xns = xmlDoc.SelectSingleNode("ELAYOUT/STRUCTURE_LIST/STRUCTURE/LAYER_REFERENCE/TRAPEZOID");                    if (xns != null)                    {                        XmlAttributeCollection attributeCol = xns.Attributes;                        //遍历自己点属性                        double width_a = Convert.ToDouble(attributeCol.GetNamedItem("width_a").Value) / 2.0;                        log.Info("XML-Width_a = " + width_a.ToString(), true);                        foreach (XmlAttribute attri in attributeCol)                        {                            if (attri.Name == "x")                            {                                attri.InnerText = ((x0 * px) * 1000000 - width_a).ToString();                                log.Info("XML-TopLeft-X = " + attri.InnerText, true);                            }                            else if (attri.Name == "y")                            {                                attri.InnerText = ((y0 * px) * 1000000 - 2.791).ToString();                                log.Info("XML-TopLeft-Y = " + attri.InnerText, true);                            }                        }                    }                    xns = xmlDoc.SelectSingleNode("ELAYOUT/STRUCTURE_LIST/STRUCTURE/LAYER_REFERENCE/RECT");                    if (xns != null)                    {                        XmlAttributeCollection attributeCol = xns.Attributes;                        double width = Convert.ToDouble(attributeCol.GetNamedItem("width").Value) / 2.0;                        //遍历自己点属性                        foreach (XmlAttribute attri in attributeCol)                        {                            if (attri.Name == "x")                            {                                attri.InnerText = ((x0 * px) * 1000000 - width).ToString();                            }                            else if (attri.Name == "y")                            {                                attri.InnerText = (((y0 * px) * 1000000) + 2 - 2.791).ToString();                            }                        }                    }                    xmlDoc.Save(MParam.FIBTemp);//保存的该XML文件,否则更新无效                    //判断是否需要PT沉积,如果需要也要修改PT的ELY文件                    if (MParam.PT)                    {                        xmlDoc = new XmlDocument();                        xmlDoc.Load(MParam.PTTemp);//加载baixml文件,xmlpath 为XML文件的路径du                        xns = xmlDoc.SelectSingleNode("ELAYOUT/STRUCTURE_LIST/STRUCTURE/LAYER_REFERENCE/RECT");                        if (xns != null)                        {                            XmlAttributeCollection attributeCol = xns.Attributes;                            double width = Convert.ToDouble(attributeCol.GetNamedItem("width").Value) / 2.0;                            //因为ELY文件里的矩形高就是负值,所以在下面的Y值加上这个值就好。                            double height = Convert.ToDouble(attributeCol.GetNamedItem("height").Value) / 1.5;                            //遍历自己点属性                            foreach (XmlAttribute attri in attributeCol)                            {                                if (attri.Name == "x")                                {                                    attri.InnerText = ((x0 * px) * 1000000 - width).ToString();                                }                                else if (attri.Name == "y")                                {                                    attri.InnerText = ((y0 * px) * 1000000 - 2.791 - height).ToString();                                }                            }                        }                        xmlDoc.Save(MParam.PTTemp);                    }                    if (hand_intervene == 1)                    {                        MessageBox.Show("Web返回数据移动是否正确?\n如果错误请手动移动到指定位置后按确认", "确认消息", MessageBoxButtons.OK);                    }                }                else                {                    arg.Message = "图像接口参数state返回值为零";                    arg.State = false;                    //SendMsg("1-12");                    if (hand_intervene == 1)                    {                        if (DialogResult.Yes != MessageBox.Show("网络参数State返回为0。\n是否继续操作?。", "确认消息", MessageBoxButtons.YesNo))                        {                            return false;                        }                    }                    else                    {                        log.Error("测量线程报错:自动定位图像接口返回0", false);                        return false;                    }                    log.Error("测量线程报错:自动定位图像接口返回0", false);                    return false;                }                //判断是否停止进程                if (key_stop)                {                    log.Info("停止键按下", true);                    return false;                }                //11.自动工具样品类型参数确定是否需要PT沉积                if (MParam.PT)                {                    if (!iSEM.CmdFIBModeFIB())                    {                        log.Error("测量线程报错:切换到SEM模式失败", false);                        return false;                    }                    Thread.Sleep(200);                    //12.根据样品类型参数确定是否需要PT沉积,控制PT针插入                    if (MParam.Is_Photograph == false && MParam.PT == true)                    {                        log.Info("测量线程:插入PT针" + arg.Message, true);                        if (!InsertPT())                        {                            arg.Message = "插入PT针失败";                            arg.State = false;                            SendMsg("2-4");                            log.Error("测量线程报错:" + arg.Message, false);                            return false;                        }                        arg.State = true;                        arg.Message = "插入PT针成功";                        SendMsg("2-4");                    }                    //判断是否停止进程                    if (key_stop)                    {                        log.Info("停止键按下", true);                        return false;                    }                    //3. 根据坐标进行PT沉积                       if (!PTWork())                    {                        arg.Message = "PT沉积失败";                        arg.State = false;                        SendMsg("2-5");                        log.Error("测量线程报错:" + arg.Message, false);                        return false;                    }                    arg.State = true;                    arg.Message = "PT沉积成功";                    SendMsg("2-5");                    //判断是否停止进程                    if (key_stop)                    {                        log.Info("停止键按下", true);                        return false;                    }                    //15.根据样品类型决定是否撤出PT针                    if (MParam.Is_Photograph == false && MParam.PT == true)                    {                        if (!RetractPT())                        {                            arg.Message = "撤出PT针失败";                            arg.State = false;                            SendMsg("2-6");                            log.Error("测量线程报错:" + arg.Message, false);                            return false;                        }                        arg.State = true;                        arg.Message = "撤出PT针成功";                        SendMsg("2-6");                    }                    //判断是否停止进程                    if (key_stop)                    {                        log.Info("停止键按下", true);                        return false;                    }                    if (!iSEM.CmdFIBModeSEM())                    {                        //arg.Message = "切割前SEM拍照失败。";                        //arg.State = false;                        //SendMsg("1-17");                        log.Error("测量线程报错:切换到SEM模式失败", false);                        return false;                    }                }            }            //14.保存样品1第1号孔中心位置6轴坐标1 XYZMRT到数据库,保存客户返回值信息到数据库            float[] firstPosition = iSEM.GetStagePosition();            m_cutHoles[0].Position.X = firstPosition[0];            m_cutHoles[0].Position.Y = firstPosition[1];            m_cutHoles[0].Position.Z = firstPosition[2];            m_cutHoles[0].Position.T = firstPosition[3];            m_cutHoles[0].Position.R = firstPosition[4];            m_cutHoles[0].Position.M = firstPosition[5];            //这里要调用文件保存功能            arg.Message = "坐标1(" + firstPosition[0].ToString() + ","                + firstPosition[1].ToString() + ","                + firstPosition[2].ToString() + ","                + firstPosition[3].ToString() + ","                + firstPosition[4].ToString() + ","                + firstPosition[5].ToString() + ")";            arg.State = true;            //SendMsg("1-16");            //判断是否停止进程            if (key_stop)            {                log.Info("停止键按下", true);                return false;            }            return true;        }        /// <summary>        /// 14. FIB切割        /// </summary>        /// <returns></returns>        public bool FIBCross()        {            int state = 0;            if (!iSEM.CmdFIBModeFIB())            {                arg.Message = "切换到FIB模式失败。";                arg.State = false;                SendMsg("2-7");                log.Error("测量线程报错:切换到SEM模式失败", false);                return false;            }            arg.Message = "切换到FIB模式成功。";            arg.State = true;            SendMsg("2-7");            Thread.Sleep(1000);            iSEM.SetMagnification(MParam.Location_Magnification);            float current = iSEM.GetMagnification();            while (Math.Abs(current - MParam.Location_Magnification) > 1)            {                iSEM.SetMagnification(MParam.Location_Magnification);                Thread.Sleep(200);                current = iSEM.GetMagnification();            }            Thread.Sleep(2000);            //14.自动控制FIB切割            //1.根据参数设置FIB草率时间(使图清晰),设置梯形上下边及深度、设置束流            //2.控制FIB进行切割            //以上1、2步全部用ELY文件代替            if (!FIBWork())            {                arg.Message = "FIB切割失败";                arg.State = false;                SendMsg("2-8");                log.Error("测量线程报错:" + arg.Message, false);                return false;            }            arg.State = true;            arg.Message = "FIB切割成功";            SendMsg("2-8");            Thread.Sleep(300);            //判断是否停止进程            if (key_stop)            {                log.Info("停止键按下", true);                return false;            }            //做切割后SEM的拍照            log.Info("测量线程:切割后SEM拍照", true);            if (!iSEM.CmdFIBModeSEM())            {                                log.Error("测量线程报错:切换到SEM模式失败", false);                return false;            }            Thread.Sleep(1000);            return true;        }        /// <summary>        /// 16.自动调整SEM找到切割位置,这里不是简单的拉直旋转        /// </summary>        /// <returns></returns>        public bool FindCross()        {            float x2 = 0, y2 = 0;            int state = 0;            //切换到SEM模式            if (!iSEM.CmdFIBModeSEM())            {                arg.Message = "SEM模式切换失败";                arg.State = false;                SendMsg("3-0");                log.Error("测量线程报错:" + arg.Message, false);                return false;            }            arg.State = true;            arg.Message = "SEM模式切换成功";            SendMsg("3-0");            arg.Picture_Information.Work_Status = "SEM";            Thread.Sleep(1000);            //判断是否停止进程            if (key_stop)            {                log.Info("停止键按下", true);                return false;            }            //1.控制SEM放大到300倍            log.Info("能谱电压设置:" + MParam.Location_Voltage.ToString("0.0"));            if (!iSEM.SetSEMVoltage(MParam.Location_Voltage))            {                arg.Message = "电压设置" + MParam.Location_Voltage.ToString("0.0") + "失败";                arg.State = false;                SendMsg("3-1");                log.Error("测量线程报错:" + arg.Message, false);                return false;            }            Thread.Sleep(200);            //iSEM.SetAutoVideoBrightnessAndContrast();            //add by sun 2020-12-17 解决3大类样品FIB下亮度过白导致无法识别问题            float m_TempBrightness = 50.0f;            float m_TempContrast = 30.0f;            if (MParam.SampleName == "3")            {                m_TempBrightness = 48.0f;                m_TempContrast = 29.0f;            }            //add by sun 2020-12-17 解决3大类样品FIB下亮度过白导致无法识别问题                        iSEM.SetAutoVideoOff();            Thread.Sleep(200);            iSEM.SetBrightness(m_TempBrightness); //50.0f            Thread.Sleep(200);            iSEM.SetContrast(m_TempContrast); //30.0f            Thread.Sleep(2000);            float mag = MParam.Location_Magnification / 3;            if (mag < 200)            {                //add by sun 2020-12-17 设置找梯形照片的放大倍数为400,原来设置成200容易识别错乱                if (MParam.SampleName == "3")                    mag = 400;                else //add by sun 2020-12-17 设置找梯形照片的放大倍数为400,原来设置成200容易识别错乱                    mag = 200;            }            if (!iSEM.SetMagnification(mag))            {                arg.Message = "放大" + mag.ToString("0.0") + "倍失败";                arg.State = false;                SendMsg("3-1");                log.Error("测量线程报错:" + arg.Message, false);                return false;            }            Thread.Sleep(200);            float current = iSEM.GetMagnification();            Thread.Sleep(200);            while (Math.Abs(current - mag) > 2)            {                iSEM.SetMagnification(mag);                Thread.Sleep(200);                current = iSEM.GetMagnification();                Thread.Sleep(200);            }            arg.State = true;            arg.Message = "放大" + mag.ToString("0.0") + "倍成功";            SendMsg("3-1");            Thread.Sleep(2000);            //判断是否停止进程            if (key_stop)            {                log.Info("停止键按下", true);                return false;            }            //3.控制SEM拍照            //String fileName4 = data_path + "\\" + m_cutHoles[m_nWorkHoleNo].HoleName + "_" + mag.ToString("0") + "_" + ImageName4;            //add by zjx 2020-12-21 根据客户的需求修改图片的名称            String fileName4 = data_path + "\\" + MParam.Firm + "-" + mag.ToString("0") + "-" + m_cutHoles[m_nWorkHoleNo].HoleName + "-" + ImageName4;            //add by zjx 2020-12-21 根据客户的需求修改图片的名称 end            log.Info("fileName4====================" + fileName4, true);            arg.Picture_Information.Picture_FullPath = fileName4;            arg.Picture_Information.Work_Voltage = iSEM.GetSEMVoltage();            Thread.Sleep(200);            arg.Picture_Information.Magnification = iSEM.GetMagnification();            Thread.Sleep(200);            arg.Picture_Information.Work_Distance = iSEM.GetWorkingDistance();            Thread.Sleep(200);            //拍照前改变速度,延时            //add by sun 2020-12-15 增加不同样品扫描速度参数,每大类样品3种扫描速度            iSEM.CmdFocusScanSpeed(MParam.ScanSpeedHigh);//iSEM.CmdSaveRate();            //add by sun 2020 - 12 - 15 增加不同样品扫描速度参数,每大类样品3种扫描速度 end            Thread.Sleep(200);            cycle_time = iSEM.GetCycleTime();            Thread.Sleep(Convert.ToInt32(cycle_time) + 100);            if (!GetImage(fileName4))            {                arg.State = false;                arg.Message = "SEM拍照找切割位置失败";                SendMsg("3-2");                log.Error("测量线程报错:" + arg.Message, false);                return false;            }            arg.Picture_Information.Picture_FullPath = fileName4;            arg.State = true;            arg.Message = "SEM拍照成功";            SendMsg("3-2");            iSEM.CmdFocusScanSpeed(MParam.ScanSpeedNormal);//CmdFocusRate(4);            Thread.Sleep(200);            cycle_time = iSEM.GetCycleTime();            Thread.Sleep(Convert.ToInt32(cycle_time) + 100);            //判断是否停止进程            if (key_stop)            {                return false;            }            //4.将照片传给客户,获取偏移坐标,以及偏移角度            //5.根据坐标控制SEM移动到切孔位置,居中            log.Info("测量线程:图像处理接口,准备移动样品台", true);            log.Info("文件名=" + fileName4, true);            ImagePro.Img_Trapezoid_Top_Center_Position(fileName4, Convert.ToInt32(MParam.SampleName), MParam.Firm, out x2, out y2, out state);            log.Info("梯形中心点返回数据=" + x2.ToString() + ", " + y2.ToString(), true);            log.Info("准备移动样品台返回状态=" + state.ToString(), true);            if (state == 1)            {                //1. 根据客户PT沉积坐标控制FIB调整到中心位置???????                if (!MoveToPixByMoveStage(x2, y2))                {                    arg.State = false;                    arg.Message = "移动到新(" + x2.ToString() + "," + y2.ToString() + ")位置失败";                    SendMsg("3-3");                    log.Error("测量线程报错:" + arg.Message, false);                    return false;                }                //判断是否移动完成                while (true)                {                    Thread.Sleep(4000);                    if (iSEM.GetStageIs() == 0)                    {                        break;                    }                }                arg.State = true;                arg.Message = "移动到新(" + x2.ToString() + "," + y2.ToString() + ")位置成功";                SendMsg("3-3");                //高倍到低倍不进行对焦                //拍照前改变速度,延时                //add by sun 2020-12-15 增加不同样品扫描速度参数,每大类样品3种扫描速度                iSEM.CmdFocusScanSpeed(MParam.ScanSpeedHigh);//iSEM.CmdSaveRate();                //add by sun 2020 - 12 - 15 增加不同样品扫描速度参数,每大类样品3种扫描速度 end                Thread.Sleep(200);                cycle_time = iSEM.GetCycleTime();                Thread.Sleep(Convert.ToInt32(cycle_time) + 100);                //String fileName10 = data_path + "\\" + m_cutHoles[m_nWorkHoleNo].HoleName + "_" + mag.ToString("0") + "_" + ImageName10;                //add by zjx 2020-12-21 根据客户的需求修改图片的名称                String fileName10 = data_path + "\\" + MParam.Firm + "-" + mag.ToString("0") + "-" + m_cutHoles[m_nWorkHoleNo].HoleName + "-" + ImageName10;                //add by zjx 2020-12-21 根据客户的需求修改图片的名称 end                 log.Info("fileName10====================" + fileName10, true);                if (!GetImage(fileName10))                {                                        log.Error("测量线程报错:找到已切割的位置拍照失败", false);                }                iSEM.CmdFocusScanSpeed(MParam.ScanSpeedNormal);//CmdFocusRate(4);                Thread.Sleep(200);                cycle_time = iSEM.GetCycleTime();                Thread.Sleep(Convert.ToInt32(cycle_time) + 100);                if (hand_intervene == 1)                {                    MessageBox.Show("Web返回数据移动是否正确?\n如果错误请手动移动到指定位置后按确认", "确认消息", MessageBoxButtons.OK);                }            }            else            {                arg.Message = "图像接口参数state返回值为零";                arg.State = false;                SendMsg("3-3");                if (hand_intervene == 1)                {                    if (DialogResult.Yes != MessageBox.Show("网络参数State返回为0。\n是否继续操作?。", "确认消息", MessageBoxButtons.YesNo))                    {                        return false;                    }                }                else                {                    return false;                }                log.Error("测量线程报错:" + arg.Message, false);                return false;            }            //判断是否停止进程            if (key_stop)            {                log.Info("停止键按下", true);                return false;            }            return true;        }        /// <summary>        /// 17.自动控制SEM拍截面照        /// </summary>        /// <returns></returns>        public bool ShotSection(ref List<String> limg_path, ref List<float> lsize)        {            int state = 0;            #region 设置拍照的电压            log.Info("测量线程:设置拍照电压" + MParam.Photograph_Voltage.ToString(), true);            //1、放大倍数参数photograph_            if (!iSEM.SetSEMVoltage(MParam.Photograph_Voltage))            {                arg.Message = "电压设置" + MParam.Photograph_Voltage.ToString("0.0") + "失败";                arg.State = false;                SendMsg("3-4");                log.Error("测量线程报错:" + arg.Message, false);                return false;            }            //add            #endregion            Thread.Sleep(200);            #region 设置拍照的放大倍数            log.Info("测量线程:设置拍照放大倍数====" + MParam.Photograph_Magnification.ToString(), true);            if (!iSEM.SetMagnification(MParam.Photograph_Magnification))            {                arg.Message = "放大倍数调整失败";                arg.State = false;                SendMsg("3-4");                log.Error("测量线程报错:" + arg.Message, false);                return false;            }            float set = MParam.Photograph_Magnification;            float current = iSEM.GetMagnification();            while (Math.Abs(current - set) > 1)            {                iSEM.SetMagnification(MParam.Photograph_Magnification);                Thread.Sleep(200);                current = iSEM.GetMagnification();            }            arg.Message = "放大" + MParam.Photograph_Magnification.ToString() + "成功";            arg.State = true;            SendMsg("3-4");            Thread.Sleep(3000 + (Int32)cycle_time);            //判断是否停止进程            if (key_stop)            {                log.Info("停止键按下", true);                return false;            }            #endregion            #region 拍摄矩形的切割孔,使用拍照的放大倍数                      //2.控制SEM自动对焦、亮度、对比度-接口            //add by sun 2020-12-16 解决第5/6类样品 2000倍对焦不好问题            if ((MParam.SampleName == "2") || (MParam.SampleName == "3"))                iSEM.SetReduced(402, 128, 600, 600);            else  //add by sun 2020-12-16 解决第5/6类样品 2000倍对焦不好问题 end                iSEM.SetReduced(402, 128, 600, 600);            Thread.Sleep(200);            //add by sun 2020 - 12 - 15 拍截面图调用蔡司接口时,要保证扫描速度5以上,自动亮度对比度功能关闭            iSEM.CmdFocusScanSpeed(MParam.ScanSpeedFocus);//CmdFocusRate(5);            //add by sun 2020 - 12 - 15 拍截面图调用蔡司接口时,要保证扫描速度5以上,自动亮度对比度功能关闭 end            Thread.Sleep(200);            cycle_time = iSEM.GetCycleTime();            Thread.Sleep(100 + Convert.ToInt32(cycle_time));            log.Info("测量线程:17.自动控制SEM拍截面照-关闭自动亮度对比度开始!", true);            if (!iSEM.SetAutoVideoOff())            {                log.Error("测量线程报错:关闭自动亮度对比度失败", false);                return false;            }            Thread.Sleep(5000);            log.Info("测量线程:17.自动控制SEM拍截面照-关闭自动亮度对比度结束!", true);            log.Info("测量线程:17.自动控制SEM拍截面照-自动对焦开始!", true);            if (ImageFocus1(true))            {                arg.Message = "自动对焦完成";                arg.State = true;                SendMsg("3-5");            }            else            {                arg.Message = "自动对焦失败";                arg.State = false;                SendMsg("3-5");                log.Error("测量线程报错:" + arg.Message, false);                return false;            }            Thread.Sleep(1000);            log.Info("测量线程:17.自动控制SEM拍截面照-自动对焦结束!", true);            iSEM.CloseReduced();            Thread.Sleep(200);            cycle_time = iSEM.GetCycleTime();            Thread.Sleep(200 + Convert.ToInt32(cycle_time));            //判断是否停止进程            if (key_stop)            {                log.Info("停止键按下", true);                return false;            }            //add by sun 2020-12-17 解决3大类样品FIB下亮度过白导致无法识别问题            float m_TempBrightness = 50.0f;            float m_TempContrast = 30.0f;            if (MParam.SampleName == "3")            {                m_TempBrightness = 50f;                m_TempContrast = 29f;                iSEM.SetBrightness(m_TempBrightness); //50.0f                Thread.Sleep(200);                iSEM.SetContrast(m_TempContrast); //30.0f                Thread.Sleep(200);            }            //add by sun 2020-12-17 解决3大类样品FIB下亮度过白导致无法识别问题 end            if (!iSEM.SetAutoVideoBrightnessAndContrast())            {                log.Error("测量线程报错:自动开启亮度对比度失败", false);                return false;            }            Thread.Sleep(5000);            //3、设置SEM补偿角度            if (MParam.Is_Photograph == false)            {                log.Info("测量线程:角度补偿" + MParam.Correction_Angle.ToString() + "度", true);                if (!TiltCorrection(MParam.Correction_Angle))                {                    arg.Message = "设置SEM进行角度补偿" + MParam.Correction_Angle.ToString("0") + "度失败";                    arg.State = false;                    SendMsg("3-6");                    log.Error("测量线程报错:" + arg.Message, false);                    return false;                }                arg.State = true;                arg.Message = "设置SEM进行角度补偿" + MParam.Correction_Angle.ToString("0") + "度成功";                SendMsg("3-6");                Thread.Sleep(200);                //判断是否停止进程                if (key_stop)                {                    log.Error("停止键按下", false);                    return false;                }            }            //4、拍照,5、保存照片            //String fileName5 = data_path + "\\" + m_cutHoles[m_nWorkHoleNo].HoleName + "_" + MParam.Photograph_Magnification.ToString("0") + "_" + ImageName5;            //add by zjx 2020-12-21 根据客户的需求修改图片的名称            String fileName5 = data_path + "\\" + MParam.Firm + "-" + MParam.Photograph_Magnification.ToString("0") + "-" + m_cutHoles[m_nWorkHoleNo].HoleName + "-" + ImageName5;            //add by zjx 2020-12-21 根据客户的需求修改图片的名称 end             log.Info("fileName5====================" + fileName5, true);            arg.Picture_Information.Picture_FullPath = fileName5;            arg.Picture_Information.Work_Status = "SEM";            arg.Picture_Information.Work_Voltage = iSEM.GetSEMVoltage();            Thread.Sleep(200);            arg.Picture_Information.Magnification = iSEM.GetMagnification();            Thread.Sleep(200);            arg.Picture_Information.Work_Distance = iSEM.GetWorkingDistance();            Thread.Sleep(200);            //拍照前改变速度,延时            //add by sun 2020-12-15 增加不同样品扫描速度参数,每大类样品3种扫描速度            iSEM.CmdFocusScanSpeed(MParam.ScanSpeedHigh);//iSEM.CmdSaveRate();            //add by sun 2020 - 12 - 15 增加不同样品扫描速度参数,每大类样品3种扫描速度 end            Thread.Sleep(200);            cycle_time = iSEM.GetCycleTime();            Thread.Sleep(Convert.ToInt32(cycle_time) * 2);            if (!GetImage(fileName5))            {                arg.Message = "SEM拍照失败";                arg.State = false;                SendMsg("3-7");                log.Error("测量线程报错:" + arg.Message, false);                return false;            }            arg.Picture_Information.Picture_FullPath = fileName5;            arg.State = true;            arg.Message = "SEM拍照成功";            SendMsg("3-7");            iSEM.CmdFocusScanSpeed(MParam.ScanSpeedNormal);//CmdFocusRate(4);            Thread.Sleep(200);            cycle_time = iSEM.GetCycleTime();            Thread.Sleep(Convert.ToInt32(cycle_time) + 100);            //判断是否停止进程            if (key_stop)            {                log.Info("停止键按下", true);                return false;            }            #endregion            if (MParam.Is_Photograph == false)            {                #region 对当前矩形进行旋转校正                //8,计算切割面区域偏移角度及方向                float degree = 0;                int direction = 0;                ImagePro.Img_Center_Position_OffsetAngle_Direction(fileName5, Convert.ToInt32(MParam.SampleName), MParam.Firm, out degree, out direction, out state);                log.Info("测量线程:2000倍===拍照角度移动,输入图像" + fileName5 + "输出角度为" + degree.ToString() + "输出方向为" + direction.ToString() + "返回值为" + state.ToString(), true);                log.Info("样品" + m_nWorkHoleNo.ToString() + "计算切割面区域的角度=" + degree.ToString(), true);                //接口返回像素,*pixelsize,得到坐标点。判断移动方式                if (state == 1)                {                    //梯形角度                    iSEM.SetScanRotationOn();                    Thread.Sleep(200);                    //20201128陈工要求,谭博返回角度*0.7                    iSEM.SetScanRotation(Convert.ToSingle(degree * MParam.ScanRotCor));                    Thread.Sleep(200);                    arg.State = true;                    arg.Message = "图像接口返回角度为:" + degree.ToString();                    SendMsg("3-8");                    if (hand_intervene == 1)                    {                        MessageBox.Show("Web返回数据移动是否正确?\n如果错误请手动移动到指定位置后按确认", "确认消息", MessageBoxButtons.OK);                    }                }                else                {                    arg.Message = "图像接口参数State返回值为零";                    arg.State = false;                    SendMsg("3-8");                    if (hand_intervene == 1)                    {                        if (DialogResult.Yes != MessageBox.Show("网络参数State返回为0。\n是否继续操作?。", "确认消息", MessageBoxButtons.YesNo))                        {                            return false;                        }                    }                    else                    {                        //return false;                    }                    log.Error("测量线程报错:" + arg.Message, false);                }                //判断是否停止进程                if (key_stop)                {                    log.Info("停止键按下", true);                    return false;                }                Thread.Sleep(200);                //12拍照                //String fileName6 = data_path + "\\" + m_cutHoles[m_nWorkHoleNo].HoleName + "_" + MParam.Photograph_Magnification.ToString("0") + "_" + ImageName6;                //add by zjx 2020-12-21 根据客户的需求修改图片的名称                String fileName6 = data_path + "\\" + MParam.Firm + "-" + MParam.Photograph_Magnification.ToString("0") + "-" + m_cutHoles[m_nWorkHoleNo].HoleName + "-" + ImageName6;                //add by zjx 2020-12-21 根据客户的需求修改图片的名称 end                 log.Info("fileName6====================" + fileName6, true);                arg.Picture_Information.Picture_FullPath = fileName6;                arg.Picture_Information.Work_Status = "SEM";                arg.Picture_Information.Work_Voltage = iSEM.GetSEMVoltage();                Thread.Sleep(200);                arg.Picture_Information.Magnification = iSEM.GetMagnification();                Thread.Sleep(200);                arg.Picture_Information.Work_Distance = iSEM.GetWorkingDistance();                Thread.Sleep(200);                //拍照前改变速度,延时                //add by sun 2020-12-15 增加不同样品扫描速度参数,每大类样品3种扫描速度                iSEM.CmdFocusScanSpeed(MParam.ScanSpeedHigh);//iSEM.CmdSaveRate();                //add by sun 2020 - 12 - 15 增加不同样品扫描速度参数,每大类样品3种扫描速度 end                Thread.Sleep(200);                cycle_time = iSEM.GetCycleTime();                Thread.Sleep(Convert.ToInt32(cycle_time) + 100);                if (!GetImage(fileName6))                {                    arg.Message = "SEM拍照失败";                    arg.State = false;                    SendMsg("3-9");                    log.Error("测量线程报错:" + arg.Message, false);                    return false;                }                arg.Picture_Information.Picture_FullPath = fileName6;                arg.State = true;                arg.Message = "SEM拍照成功";                SendMsg("3-9");                iSEM.CmdFocusScanSpeed(MParam.ScanSpeedNormal);//CmdFocusRate(4);                Thread.Sleep(200);                cycle_time = iSEM.GetCycleTime();                Thread.Sleep(Convert.ToInt32(cycle_time) + 100);                //判断是否停止进程                if (key_stop)                {                    log.Info("停止键按下", true);                    return false;                }                #endregion                #region 获取两个位置上及放大倍数                //计算两个测量区域坐标                List<System.Drawing.Point> ct = new List<System.Drawing.Point>();                List<float> mag = new List<float>();                System.Drawing.Point ct0;                float mag1, mag2, magMax;                //log.Info("测量线程:图像处理接口,计算两个放大区域坐标,输入图像" + fileName6.ToString() + "控制失败", true);                ImagePro.Img_Measure_Region_Position(fileName6, Convert.ToInt32(MParam.SampleName), MParam.Firm, out ct, out mag, out ct0, out state);                string s = "";                for (int i = 0; i < ct.Count; i++)                {                    s += "输出观测点" + i.ToString() + "为(" + ct[i].X.ToString() + "," + ct[i].Y.ToString() + ")"                    + "放大倍数=" + mag[i];                }                log.Info("测量线程:图像处理接口返回值为" + state.ToString() +                    ",计算两个放大区域坐标,输入图像" + fileName6.ToString() +                    "输入样品" + Convert.ToInt32(MParam.SampleName) +                    "输入厂商" + MParam.Firm.ToString() +                    s +                  "输出对焦点为(" + ct0.X.ToString() + "," + ct0.Y.ToString() + ")", true);                #endregion                if (state == 1 && ct.Count != 0 && mag.Count != 0)                {                    arg.State = true;                    arg.Message = "获取位置及放大倍数成功";                    SendMsg("3-10");                    #region 记录初始设置的BeamShift的百分比和样品台XY位置                    float xs = iSEM.GetBeamShiftX();                    Thread.Sleep(200);                    float ys = iSEM.GetBeamShiftY();                    Thread.Sleep(200);                    float xpCur = iSEM.GetStageAtX();                    Thread.Sleep(200);                    float ypCur = iSEM.GetStageAtY();                    Thread.Sleep(200);                    log.Info("测量线程:原来的光束偏移量x = " + xs.ToString()                        + "y=" + ys.ToString() + ","                        + "原来样品台的位置x= " + xpCur.ToString()                        + "y=" + ypCur.ToString(), true);                    #endregion                    //找到放大倍数最大值                    magMax = mag[0];                    for (int m = 1; m < mag.Count; m++)                    {                        if (mag[m] > magMax)                        {                            magMax = mag[m];                        }                    }                    #region 移动到梯形左上角                    //20201127将视野移动到梯形左上角位置                    MoveToPix(ct0.X, ct0.Y);                    log.Info("测量线程:移动到对焦点( " + ct0.X.ToString()                        + "," + ct0.Y.ToString() + ")", true);                    //关闭自动亮度对比度                    iSEM.SetAutoVideoOff();                    Thread.Sleep(2000);                    //add by sun 2020-12-17 解决3大类样品FIB下亮度过白导致无法识别问题                    if (MParam.SampleName == "3")                    {                        m_TempBrightness = 50f;                        m_TempContrast = 29f;                        iSEM.SetBrightness(m_TempBrightness); //50.0f                        Thread.Sleep(200);                        iSEM.SetContrast(m_TempContrast); //30.0f                        Thread.Sleep(200);                    }                    //add by sun 2020-12-17 解决3大类样品FIB下亮度过白导致无法识别问题 end                    //add by sun 2020-12-16 解决第5/6类样品 6000倍对焦不好问题                    if (MParam.SampleName == "3")                    {                        iSEM.SetReduced(402, 128, 480, 450);                    }                    else                    {                        iSEM.SetReduced(402, 128, 480, 450);                    }                    Thread.Sleep(200);                    //add by sun 2020-12-15 拍截面图调用蔡司接口时,要保证扫描速度5以上,自动亮度对比度功能关闭                    iSEM.CmdFocusScanSpeed(MParam.ScanSpeedFocus);//CmdFocusRate(5);                    //add by sun 2020-12-15 拍截面图调用蔡司接口时,要保证扫描速度5以上,自动亮度对比度功能关闭 end                    Thread.Sleep(200);                    cycle_time = iSEM.GetCycleTime();                    Thread.Sleep(100 + Convert.ToInt32(cycle_time));                    //放大到6000倍                    iSEM.SetMagnification(magMax / 2);                    Thread.Sleep(100 + Convert.ToInt32(cycle_time));                    set = magMax / 2;                    current = iSEM.GetMagnification();                    while (Math.Abs(current - set) > 1)                    {                        iSEM.SetMagnification(set);                        Thread.Sleep(200);                        current = iSEM.GetMagnification();                    }                    log.Info("========测量线程:开始自动聚焦 " + set.ToString() + "倍", true);                    if (MParam.SampleName == "3")                    {                        //add by zjx 2020-12-18 修改亮度对比度 50 29 更成 50 30                        iSEM.SetBrightness(50.0f); //50.0f                        Thread.Sleep(200);                        iSEM.SetContrast(30.0f); //30.0f                        Thread.Sleep(200);                        //add by zjx 2020-12-18 修改亮度对比度 50 29 更成 50 30 end                    }                    //自动对焦                    if (!ImageFocus1(true))                    {                        log.Error("========测量线程:自动聚焦失败!" + set.ToString() + "倍", false);                        return false;                    }                    log.Info("========测量线程:自动聚焦成功!" + set.ToString() + "倍", true);                    Thread.Sleep(1000);                                       //放大到10000倍                    iSEM.SetMagnification(magMax);                    Thread.Sleep(100 + Convert.ToInt32(cycle_time));                    set = magMax;                    current = iSEM.GetMagnification();                    while (Math.Abs(current - set) > 1)                    {                        iSEM.SetMagnification(set);                        Thread.Sleep(200);                        current = iSEM.GetMagnification();                    }                    log.Info("========测量线程:开始自动聚焦 " + set.ToString() + "倍", true);                    //自动对焦                    if (!ImageFocus1(true))                    {                        log.Info("========测量线程:自动聚焦失败!" + set.ToString() + "倍", true);                        return false;                    }                    log.Info("========测量线程:自动聚焦成功!" + set.ToString() + "倍", true);                    Thread.Sleep(1000);                    iSEM.CloseReduced();                    Thread.Sleep(200);                    cycle_time = iSEM.GetCycleTime();                    Thread.Sleep(100 + Convert.ToInt32(cycle_time));                    #endregion                    #region 循环拍照                    for (int n = 0; n < ct.Count; n++)                    {                        #region 恢复到拍照的状态                        iSEM.SetStageGotoX(xpCur);                        while (true)                        {                            Thread.Sleep(4000);                            if (iSEM.GetStageIs() == 0)                            {                                break;                            }                        }                        iSEM.SetStageGotoY(ypCur);                        while (true)                        {                            Thread.Sleep(4000);                            if (iSEM.GetStageIs() == 0)                            {                                break;                            }                        }                        //恢复原来的放大倍数                        if (!iSEM.SetMagnification(MParam.Photograph_Magnification))                        {                            log.Error("测量线程报错:第一个区域放大倍数" + mag[n].ToString() + "控制失败", false);                            return false;                        }                        Thread.Sleep(100 + Convert.ToInt32(cycle_time));                        set = MParam.Photograph_Magnification;                        current = iSEM.GetMagnification();                        while (Math.Abs(current - set) > 1)                        {                            iSEM.SetMagnification(set);                            Thread.Sleep(200);                            current = iSEM.GetMagnification();                        }                        //恢复BeamShift的百分比值                        iSEM.SetBeamShiftX(xs);                        Thread.Sleep(200);                        iSEM.SetBeamShiftY(ys);                        Thread.Sleep(200);                        #endregion                        #region 移动到指定点位置                        if (!MoveToPix(ct[n].X, ct[n].Y))                        {                            arg.State = false;                            arg.Message = "移动到第一个点位置失败";                            SendMsg("1-" + (35 + n).ToString());                            //移动到第一个点失败                            log.Error("测量线程报错:移动到点(" + ct[n].X.ToString() + "," + ct[n].Y.ToString() + ")失败", false);                        }                        log.Info("测量线程:移动到第1个点( " + ct[n].X.ToString()                            + "," + ct[n].Y.ToString() + ")", true);                        #endregion                        #region 如果是第一个点,则1W倍对焦                        if (n == 0)                        {                                                        log.Info("========测量线程:进入内部观察,不对焦!", true);                            //增亮图像                            iSEM.SetAutoVideoOff();                            Thread.Sleep(200);                            float currentBright = iSEM.GetBrightness();                            Thread.Sleep(200);                            float currentContrast = iSEM.GetContrast();                            Thread.Sleep(200);                            //add by sun 2020-12-17 黄工觉得太亮                            int m_BrightMore = 2;                            int m_ContrastMore = 2;                            if (MParam.SampleName == "3")                            {                                m_BrightMore = 0;                                m_ContrastMore = 0;                            }                            //add by sun 2020-12-17 黄工觉得太亮 end                            iSEM.SetBrightness(currentBright + m_BrightMore);                            Thread.Sleep(200);                            iSEM.SetContrast(currentContrast + m_ContrastMore);                            Thread.Sleep(200);                        }                        #endregion                                                #region 拍照                        if (!iSEM.SetMagnification(mag[n]))                        {                            arg.State = false;                            arg.Message = "移动到第一个点位置拍照失败";                            SendMsg("3-11");                            log.Error("测量线程报错:第一个区域放大倍数" + mag[n].ToString() + "控制失败", false);                            return false;                        }                        log.Info("========测量线程:移动到第一个点位置拍照完成!", true);                        Thread.Sleep(100 + Convert.ToInt32(cycle_time));                        set = mag[n];                        current = iSEM.GetMagnification();                        while (Math.Abs(current - set) > 1)                        {                            iSEM.SetMagnification(set);                            Thread.Sleep(200);                            current = iSEM.GetMagnification();                        }                        //获取像素大小                        lsize.Add(iSEM.GetPixelSize());                        Thread.Sleep(200);                        //String fileName7 = data_path + "\\" + m_cutHoles[m_nWorkHoleNo].HoleName + "_" + mag[n].ToString() + "_" + n.ToString() + "_" + ImageNameTwo_1;                        //add by zjx 2020-12-21 根据客户的需求修改图片的名称                        String fileName7 = data_path + "\\" + MParam.Firm + "-" + mag[n].ToString() + "-" + m_cutHoles[m_nWorkHoleNo].HoleName + "-" + n.ToString() + "-" + ImageNameTwo_1;                        //add by zjx 2020-12-21 根据客户的需求修改图片的名称 end                         log.Info("fileName7====================" + fileName7, true);                        arg.Picture_Information.Picture_FullPath = fileName7;                        arg.Picture_Information.Work_Status = "SEM";                        arg.Picture_Information.Work_Voltage = iSEM.GetSEMVoltage();                        Thread.Sleep(200);                        arg.Picture_Information.Magnification = iSEM.GetMagnification();                        Thread.Sleep(200);                        arg.Picture_Information.Work_Distance = iSEM.GetWorkingDistance();                        Thread.Sleep(200);                        //拍照前改变速度,延时                        iSEM.CmdLineScan();                        Thread.Sleep(200);                        cycle_time = iSEM.GetCycleTime();                        Thread.Sleep(Convert.ToInt32(cycle_time) + 100);                        if (!GetImage(fileName7))                        {                            arg.State = false;                            arg.Message = "移动到第一个点位置失败";                            SendMsg("3-11");                            log.Error("测量线程报错:" + arg.Message, false);                            return false;                        }                        log.Info("========测量线程:移动到第一个点位置完成!", true);                        iSEM.CmdPixelScan();                        Thread.Sleep(200);                        limg_path.Add(fileName7);                        arg.Picture_Information.Picture_FullPath = fileName7;                        arg.State = true;                        arg.Message = "移动到第一个点位置拍照成功";                        SendMsg("3-11");                        iSEM.CmdFocusScanSpeed(MParam.ScanSpeedNormal);//CmdFocusRate(4);                        Thread.Sleep(200);                        cycle_time = iSEM.GetCycleTime();                        Thread.Sleep(Convert.ToInt32(cycle_time) + 100);                        // add by zjx 在测量图上显示放大倍数和像素大小等信息                        float size = iSEM.GetPixelSize();                        SaveMeasDataPic(fileName7, mag[n], size);                        // add by zjx 在测量图上显示放大倍数和像素大小等信息 end                         #endregion                    }                    #endregion                    if (hand_intervene == 1)                    {                        MessageBox.Show("Web返回数据移动是否正确?\n如果错误请手动移动到指定位置后按确认", "确认消息", MessageBoxButtons.OK);                    }                }                else                {                    if (hand_intervene == 1)                    {                        if (DialogResult.Yes != MessageBox.Show("网络参数State返回为0。\n是否继续操作?。", "确认消息", MessageBoxButtons.YesNo))                        {                            // return false;                        }                    }                    else                    {                        //return false;                    }                    arg.State = false;                    arg.Message = "获取位置及放大倍数失败";                    SendMsg("3-10");                    log.Error("测量线程报错:" + arg.Message, false);                }                //判断是否停止进程                if (key_stop)                {                    log.Info("停止键按下", true);                    return false;                }            }                      iSEM.SetTiltAngleOff();            Thread.Sleep(200);            iSEM.SetScanRotationOff();            Thread.Sleep(200);            iSEM.SetBeamShiftX(0);            Thread.Sleep(200);            iSEM.SetBeamShiftY(0);            Thread.Sleep(200);            //判断是否停止进程            if (key_stop)            {                return false;            }            return true;        }        //第一个孔的测试过程        public bool FirstHole()         {            // add by zjx 2020-12-18 为了测试只做能谱部分            if (MParam.IsonlyEDSForDebug == true)            {                //add by sun 2020-12-17 不同样品电压、电流不一致,应设置灵活。123456类电压2000V电流200pA,7类5000V 500pA,能谱 7000V 500pA                 log.Warn("测量线程:第一孔=====设置拍照电压 123456类电压2000V电流200pA,7类5000V 500pA,能谱 7000V 500pA  目前是第 " + MParam.SampleName + " 类!", true);                if (!SetVoltageAndIPROBE())                {                    log.Error("测量线程:第一孔=====设置电压电流失败!目前是第 " + MParam.SampleName + " 类!", false);                    return false;                }                //add by sun 2020-12-17 不同样品电压、电流不一致,应设置灵活。123456类电压2000V电流200pA,7类5000V 500pA,能谱 7000V 500pA end                //设置拉直的放大倍数                log.Info("测量线程:第一个孔的测试过程-设置SEM放大倍数为拉直放大倍数,放大倍数为" + MParam.Stretch_Magnification.ToString(), true);                if (!iSEM.SetMagnification(MParam.Stretch_Magnification))                {                    log.Error("测量线程报错:第一个孔的测试过程-设置SEM放大倍数为拉直放大倍数失败,放大倍数为" + MParam.Stretch_Magnification.ToString(), false);                    arg.Message = "测量线程报错:拉直放大倍数设置失败!";                    arg.State = false;                    SendMsg("0-1");                    return false;                }                float current = iSEM.GetMagnification();                while (Math.Abs(current - MParam.Stretch_Magnification) > 1)                {                    iSEM.SetMagnification(MParam.Stretch_Magnification);                    Thread.Sleep(200);                    current = iSEM.GetMagnification();                }                arg.Message = "拉直放大倍数设置成功!";                arg.State = true;                SendMsg("0-1");                Thread.Sleep(2000);                //自动化流程-每个点都需要补偿54度                if (MParam.Is_Photograph == false)                {                    log.Info("测量线程:第一个孔的测试过程-倾斜补偿角度为54度", true);                    if (!TiltCorrection(54.0f))                    {                        log.Error("测量线程报错:倾斜补偿角度为54度失败", false);                        arg.Message = "角度补偿54度失败!";                        arg.State = false;                        SendMsg("0-2");                        return false;                    }                    arg.Message = "角度补偿54度成功!";                    arg.State = true;                    SendMsg("0-2");                    Thread.Sleep(1000);                    //判断是否停止进程                    if (key_stop)                    {                        log.Info("停止键按下", true);                        return false;                    }                }                // 2是5/6类样品,不需要拉直                if (MParam.SampleName != "2")                {                    log.Warn("测量线程:第一个孔的测试过程-拉直操作开始!", true);                    if (!Straighten_Handle())                    {                        log.Info("测量线程报错:第一个孔的测试过程-拉直操作失败。", true);                        return false;                    }                    log.Info("测量线程:第一个孔的测试过程-拉直操作结束!", true);                    //判断是否停止进程                    if (key_stop)                    {                        log.Info("停止键按下。", true);                        return false;                    }                }                else                {                    arg.Message = "拉直操作自动对焦成功!";                    arg.State = true;                    SendMsg("1-0");                    Thread.Sleep(1000);                    arg.Message = "拉直拍照成功!";                    arg.Picture_Information.Picture_FullPath = "";                    arg.State = true;                    SendMsg("1-1");                    Thread.Sleep(1000);                    arg.Message = "拉直操作完成";                    arg.State = true;                    SendMsg("1-2");                    Thread.Sleep(1000);                }                //13. 自动 定位功能 PT沉积                 log.Warn("测量线程:第一个孔的测试过程-自动定位开始!", true);                if (!GetPoistion())                {                    log.Error("测量线程报错:自动定位失败,程序退出。", false);                    return false;                }                log.Info("测量线程:第一个孔的测试过程-自动定位结束!", true);                //判断是否停止进程                if (key_stop)                {                    log.Info("停止键按下。", true);                    return false;                }                //14.自动控制FIB切割    del by sun 2020-12-15 temp                            if (MParam.Is_Photograph == false)                {                    if (MParam.IsCutingForDebug)                    {                        log.Warn("测量线程:第一个孔的测试过程-14.自动控制FIB切割开始!==" + MParam.IsCutingForDebug, true);                        if (!FIBCross())                        {                            log.Error("测量线程报错:自动控制FIB切割失败。", false);                            return false;                        }                        log.Info("测量线程:第一个孔的测试过程-14.自动控制FIB切割结束!", true);                    }                }                //del by sun 2020-12-15 temp end                //判断是否停止进程                if (key_stop)                {                    return false;                }                //16.找到切割位置                if (MParam.Is_Photograph == false)                {                    log.Info("测量线程:第一个孔的测试过程-16.找到切割位置开始!", true);                    if (!FindCross())                    {                        return false;                    }                    log.Info("测量线程:第一个孔的测试过程-16.找到切割位置结束!", true);                    //判断是否停止进程                    if (key_stop)                    {                        return false;                    }                }                log.Warn("测量线程:第一个孔的测试过程-17.自动控制SEM拍截面照开始", true);                //将过程17最后的拍照图片提出给18步进行调用                List<String> limg_path = new List<string>();                List<float> lsize = new List<float>();                //17.自动控制SEM拍截面照                if (!ShotSection(ref limg_path, ref lsize))                {                    log.Error("拍截面照失败!");                    return false;                }                log.Info("测量线程:第一个孔的测试过程-17.自动控制SEM拍截面照结束!", true);                //判断是否停止进程                if (key_stop)                {                    return false;                }                             //18.自动层高分析                if (MParam.Is_Photograph == false)                {                    log.Warn("测量线程:第一个孔的测试过程-18.自动层高分析开始", true);                    float size = iSEM.GetPixelSize();                    int state = 1;                    ImagePro.Img_Measure_Height(limg_path, lsize, data_path + "\\", Convert.ToInt32(MParam.SampleName), MParam.Firm, out state);                    if (state == 0)                    {                        arg.Message = "测量尺寸失败";                        arg.State = false;                        SendMsg("3-12");                        return false;                    }                    arg.State = true;                    arg.Message = "测量尺寸成功";                    SendMsg("3-12");                    log.Info("测量线程:第一个孔的测试过程-18.自动层高分析结束!", true);                }            }            //add by zjx 2020-12-18 为了测试只做能谱部分 end            //19.能谱分析            if (MParam.EDS)            {                log.Warn("测量线程:第一个孔的测试过程-19.能谱分析开始===" + MParam.EDS, true);                EDS_Analysis();                log.Info("测量线程:第一个孔的测试过程-19.能谱分析结束===" + MParam.EDS, true);            }            //20.复位            log.Info("===========测量线程:20.复位开始", true);            BeamShiftReset();            return true;        }        //非第一个孔的测试过程        public bool OtherHole()        {            //add by sun 2020-12-17 不同样品电压、电流不一致,应设置灵活。123456类电压2000V电流200pA,7类5000V 500pA,能谱 7000V 500pA             log.Warn("测量线程:非第一孔==设置拍照电压 123456类电压2000V电流200pA,7类5000V 500pA,能谱 7000V 500pA  目前是第 " + MParam.SampleName + " 类!", true);            if (!SetVoltageAndIPROBE())            {                log.Error("测量线程:非第一孔==设置电压电流失败!目前是第 " + MParam.SampleName + " 类!", false);                return false;            }            //add by sun 2020-12-17 不同样品电压、电流不一致,应设置灵活。123456类电压2000V电流200pA,7类5000V 500pA,能谱 7000V 500pA end            //设置拉直的放大倍数            log.Info("设置拉直放大倍数!");            if (!iSEM.SetMagnification(MParam.Stretch_Magnification))            {                log.Error("拉直放大倍数设置失败,程序退出。", false);                arg.Message = "拉直放大倍数设置失败!";                arg.State = false;                SendMsg("0-1");                return false;            }            float current = iSEM.GetMagnification();            while (Math.Abs(current - MParam.Stretch_Magnification) > 1)            {                iSEM.SetMagnification(MParam.Stretch_Magnification);                Thread.Sleep(200);                current = iSEM.GetMagnification();            }            arg.Message = "拉直放大倍数设置成功!";            arg.State = true;            SendMsg("0-1");            Thread.Sleep(2000);            //自动化流程-每个点都需要补偿54度            if (MParam.Is_Photograph == false)            {                log.Info("角度补偿54度!");                if (!TiltCorrection(54.0f))                {                    arg.Message = "角度补偿54度失败!";                    arg.State = false;                    SendMsg("0-2");                    return false;                }                arg.Message = "角度补偿54度成功!";                arg.State = true;                SendMsg("0-2");                Thread.Sleep(2000);                //判断是否停止进程                if (key_stop)                {                    return false;                }            }            if (MParam.SampleName != "2")            {                log.Warn("开始进行拉直操作!");                if (!Straighten_Handle())                {                    log.Info("测量线程报错:拉直操作失败。", true);                    return false;                }                //判断是否停止进程                if (key_stop)                {                    log.Info("停止键按下。", true);                    return false;                }            }            else            {                arg.Message = "拉直操作自动对焦成功!";                arg.State = true;                SendMsg("1-0");                Thread.Sleep(1000);                arg.Message = "拉直拍照成功!";                arg.Picture_Information.Picture_FullPath = "";                arg.State = true;                SendMsg("1-1");                Thread.Sleep(1000);                arg.Message = "拉直操作完成";                arg.State = true;                SendMsg("1-2");            }            //13. 自动 定位功能            log.Info("开始进行自动定位!");            if (!GetPoistion())            {                return false;            }            //判断是否停止进程            if (key_stop)            {                return false;            }            //14.自动控制FIB切割            if (MParam.Is_Photograph == false)            {                log.Warn("开始进行FIB切割!");                if (!FIBCross())                {                    return false;                }            }            //判断是否停止进程            if (key_stop)            {                return false;            }            // 16.找到切割位置            if (MParam.Is_Photograph == false)            {                log.Warn("开始找切割位置!");                if (!FindCross())                {                    return false;                }                //判断是否停止进程                if (key_stop)                {                    return false;                }            }            //将过程17最后的拍照图片提出给18步进行调用            List<String> limg_path = new List<string>();            List<float> lsize = new List<float>();            //17.自动控制SEM拍截面照            log.Warn("开始控制SEM拍截面照!");            if (!ShotSection(ref limg_path, ref lsize))            {                //return false;            }            //判断是否停止进程            if (key_stop)            {                return false;            }                  //18.自动层高分析            if (MParam.Is_Photograph == false)            {                log.Warn("开始进行层高分析!");                float size = iSEM.GetPixelSize();                int state = 1;                ImagePro.Img_Measure_Height(limg_path, lsize, data_path + "\\", Convert.ToInt32(MParam.SampleName), MParam.Firm, out state);                if (state == 0)                {                    arg.Message = "测量尺寸失败";                    arg.State = false;                    SendMsg("3-12");                    return false;                }                arg.State = true;                arg.Message = "测量尺寸成功";                SendMsg("3-12");            }            //19.能谱分析            if (MParam.EDS)            {                log.Warn("开始进行能谱分析!");                EDS_Analysis();            }            return true;        }        //测试完第一个孔后的样品台初始化操作。        //再调用CommonWork执行非第一个孔的测试过程        public bool OtherHole_Init()        {            CutHole currentHole = m_cutHoles[m_nWorkHoleNo];            #region 初始化            //1、不只拍照,且不是倾斜观测,则移动T轴            if (MParam.Is_Photograph == false && MParam.Tilt == false)            {                //4. 控制样品台T轴归0,R轴变为坐标1、Z/M轴作为坐标2保存不变                if (!iSEM.SetStageGotoT(0))                {                    log.Error("样品台归零失败", false);                    return false;                }                while (true)                {                    Thread.Sleep(5000);                    if (iSEM.GetStageIs() == 0)                    {                        break;                    }                }                //判断是否停止进程                if (key_stop)                {                    log.Info("停止键按下", true);                    return false;                }            }            //2、如果是倾斜观测,则移动Z轴            if (MParam.Tilt == true)            {                //4. 控制样品台T轴归0,R轴变为坐标1、Z/M轴作为坐标2保存不变                //if (!iSEM.SetStageGotoZ(currentHole.Position.Z - MParam.ZDistance/1000))                //20201109, Z轴降到安全的位置上                if (!iSEM.SetStageGotoZ(fSateyZ))                {                    log.Error("测量线程报错:样品台Z回到安全位置失败", false);                    return false;                }                while (true)                {                    Thread.Sleep(5000);                    if (iSEM.GetStageIs() == 0)                    {                        break;                    }                }                //判断是否停止进程                if (key_stop)                {                    log.Info("停止键按下", true);                    return false;                }            }            //3. 根据光镜坐标控制样品台移动            if (!iSEM.SetStageGotoR(currentHole.Position.R))            {                //SendMsg("移动失败");                log.Error("测量线程报错:样品台R旋转失败,目标R" + currentHole.Position.R.ToString(), false);                return false;            }            log.Info("移动R轴到=" + currentHole.Position.R.ToString(), true);            while (true)            {                Thread.Sleep(5000);                if (iSEM.GetStageIs() == 0)                {                    break;                }            }            //判断是否停止进程            if (key_stop)            {                log.Info("停止键按下", true);                return false;            }            if (!iSEM.MoveStageXY(currentHole.Position.X, currentHole.Position.Y))            {                //SendMsg("移动失败");                log.Error("测量线程报错:样品台(X,Y)移动失败失败,目标(x,y)为(" + currentHole.Position.X.ToString() + "," + currentHole.Position.X.ToString() + ")", false);                return false;            }            log.Info("移动X轴Y轴=" + currentHole.Position.X.ToString() + "  " + currentHole.Position.Y.ToString(), true);            while (true)            {                Thread.Sleep(10000);                if (iSEM.GetStageIs() == 0)                {                    break;                }            }            //判断是否停止进程            if (key_stop)            {                log.Info("停止键按下", true);                return false;            }            //4、倾斜观测时恢复Z轴            if (MParam.Tilt == true)            {                //4. 控制样品台T轴归0,R轴变为坐标1、Z/M轴作为坐标2保存不变                if (currentHole.Position.Z > 0.043)                {                    log.Error("测量线程报错:样品台Z过高,目标z" + currentHole.Position.Z.ToString(), false);                    return false;                }                if (!iSEM.SetStageGotoZ(currentHole.Position.Z))                {                    log.Error("测量线程报错:样品台Z移动失败,目标z" + currentHole.Position.Z.ToString(), false);                    return false;                }                while (true)                {                    Thread.Sleep(5000);                    if (iSEM.GetStageIs() == 0)                    {                        break;                    }                }                //判断是否停止进程                if (key_stop)                {                    log.Info("停止键按下", true);                    return false;                }            }            //5. 控制样品台,调整T轴54度、M/Z/R轴不变            if (MParam.Is_Photograph == false && MParam.Tilt == false)            {                if (!iSEM.SetStageGotoT(54))                {                    log.Info("测量线程报错:校正54度有误", true);                    return false;                }                while (true)                {                    Thread.Sleep(5000);                    if (iSEM.GetStageIs() == 0)                    {                        break;                    }                }            }            //判断是否停止进程            if (key_stop)            {                log.Info("停止键按下", true);                return false;            }            //4、设置WD            iSEM.SetWorkingDistance(m_measureFile.ListCutHole[m_nWorkHoleNo].Position.WD);            Thread.Sleep(1000);            #endregion            return true;        }        //初始化拉直操作        public bool Straighten_Handle()        {            if (MParam.Tilt)            {                //倾斜样品台,SEM视野是黑色的                log.Info("测量线程:恢复到工作位置后重新调亮图像。", true);                if (!iSEM.SetWorkingDistance(m_measureFile.ListCutHole[m_nWorkHoleNo].Position.WD))//5.1mm                {                    log.Error("测量线程报错:重新设置到标准工作距离失败。", false);                    return false;                }                Thread.Sleep(7000); //自动亮度对比度使用            }            //1、自动对焦            log.Info("测量线程:拉直操作前自动对焦开始", true);            iSEM.SetReduced(402, 128, 400, 400);            Thread.Sleep(200);            //add by sun 2020-12-15            iSEM.CmdFocusScanSpeed(MParam.ScanSpeedFocus);//CmdFocusRate(5);            //add by sun 2020-12-15 end            Thread.Sleep(200);            cycle_time = iSEM.GetCycleTime();            Thread.Sleep(100 + Convert.ToInt32(cycle_time));            //add by sun 2020-12-17 解决3大类样品FIB下亮度过白导致无法识别问题            float m_TempBrightness = 50.0f;            float m_TempContrast = 30.0f;            if (MParam.SampleName == "3")            {                m_TempBrightness = 48.0f;                m_TempContrast = 29.0f;            }            //add by sun 2020-12-18 解决1(3\4)类样品拉直太白造成无法拉直问题            if (MParam.SampleName == "1")            {                m_TempBrightness = 50.0f;                m_TempContrast = 29.0f;            }            //add by sun 2020-12-17 解决3大类样品FIB下亮度过白导致无法识别问题                iSEM.SetAutoVideoOff();            Thread.Sleep(200);            iSEM.SetBrightness(m_TempBrightness);//50.0f            Thread.Sleep(200);            iSEM.SetContrast(m_TempContrast);//30.0f            Thread.Sleep(200);            if (!ImageFocus1(true))            {                log.Error("测量线程报错:拉直操作自动对焦失败,程序退出。", false);                arg.Message = "拉直操作自动对焦失败!";                arg.State = false;                SendMsg("1-0");                return false;            }            Thread.Sleep(1000);            iSEM.CloseReduced();            Thread.Sleep(200);            cycle_time = iSEM.GetCycleTime();            Thread.Sleep(100 + Convert.ToInt32(cycle_time));            iSEM.SetAutoVideoBrightnessAndContrast();            Thread.Sleep(5000);            arg.Message = "拉直操作自动对焦成功!";            arg.State = true;            SendMsg("1-0");            //判断是否停止进程            if (key_stop)            {                log.Info("停止键按下。", true);                return false;            }            //2、拍张照片            String fileName0 = data_path + "\\" + m_cutHoles[m_nWorkHoleNo].HoleName + "_" + MParam.Stretch_Magnification.ToString("0") + "_" + ImageName0;            log.Info("测量线程:设置保存图像的是扫描速度保存图像" + fileName0, true);            //拍照前改变速度,延时            //add by sun 2020-12-15 增加不同样品扫描速度参数,每大类样品3种扫描速度            iSEM.CmdFocusScanSpeed(MParam.ScanSpeedHigh);//iSEM.CmdSaveRate();//            //add by sun 2020 - 12 - 15 增加不同样品扫描速度参数,每大类样品3种扫描速度 end            Thread.Sleep(200);            cycle_time = iSEM.GetCycleTime();            Thread.Sleep(Convert.ToInt32(cycle_time) + 100);            if (!GetImage(fileName0))            {                log.Error("测量线程报错:拉直拍照失败", false);                arg.Message = "拉直拍照失败";                arg.State = false;                SendMsg("1-1");                return false;            }            arg.Message = "拉直拍照成功!";            arg.Picture_Information.Picture_FullPath = fileName0;            arg.State = true;            SendMsg("1-1");            iSEM.CmdFocusScanSpeed(MParam.ScanSpeedNormal);//CmdFocusRate(4);            Thread.Sleep(200);            cycle_time = iSEM.GetCycleTime();            Thread.Sleep(Convert.ToInt32(cycle_time) + 100);            //3、华为接口,获取旋转角度            float degree = 0;            int direction = 0;            int state = 1;            ImagePro.Img_OffsetAngle_Direction(fileName0, Convert.ToInt32(MParam.SampleName), MParam.Firm, out degree, out direction, out state);            log.Info("测量线程:使用图像处理接口:样品" + m_nWorkHoleNo.ToString() + "初始化拉直角度=" + degree.ToString(), true);            log.Info("图像处理结果拉直角度=" + degree.ToString(), true);            log.Info("图像处理结果拉直角度=" + degree.ToString(), true);            if (state == 0)            {                log.Info("测量线程:图像处理接口参数state返回为零", false);                arg.Message = "图像处理接口参数state返回为零";                arg.State = false;                SendMsg("1-2");                if (hand_intervene == 1)                {                    if (DialogResult.Yes != MessageBox.Show("网络参数State返回为0。\n是否继续操作?。", "确认消息", MessageBoxButtons.YesNo))                    {                        return false;                    }                }                else                {                    return false;                }                return false;            }            if (direction == 2)            {                degree = -degree;            }            if (degree != 0)            {                //4、拉直,旋转R轴                log.Info("测量线程:图像拉直,旋转角度" + degree.ToString(), true);                //选择之前,先降Z轴                float Zpos = iSEM.GetStageAtZ();                Thread.Sleep(200);                log.Info("测量线程:当前Z轴位置" + Zpos.ToString() + "m", true);                if (!iSEM.SetStageGotoZ(fSateyZ))                {                    log.Error("测量线程报错:样品台Z回到安全位置失败", false);                    return false;                }                while (true)                {                    Thread.Sleep(4000);                    if (iSEM.GetStageIs() == 0)                    {                        break;                    }                }                //判断是否停止进程                if (key_stop)                {                    log.Info("停止键按下", true);                    return false;                }                iSEM.SetStageDeltaR(degree);                while (true)                {                    Thread.Sleep(4000);                    if (iSEM.GetStageIs() == 0)                    {                        break;                    }                }                if (!iSEM.SetStageGotoZ(Zpos))                {                    log.Error("测量线程报错:样品台Z回到安全位置失败", false);                    return false;                }                while (true)                {                    Thread.Sleep(4000);                    if (iSEM.GetStageIs() == 0)                    {                        break;                    }                }                //判断是否停止进程                if (key_stop)                {                    log.Info("停止键按下", true);                    return false;                }                //4、设置WD                iSEM.SetWorkingDistance(m_measureFile.ListCutHole[m_nWorkHoleNo].Position.WD);                Thread.Sleep(1000);            }            arg.Message = "拉直操作完成";            arg.State = true;            SendMsg("1-2");            return true;        }        //角度补偿        public bool TiltCorrection(float a_fAngle)        {            if (!iSEM.SetTiltAngleOn())            {                return false;            }            Thread.Sleep(200);            //恢复原始状态            if (!iSEM.SetTiltAngle(a_fAngle))            {                return false;            }            return true;        }        //拍图        public bool GetImage(String a_fileName)        {            log.Info("获取分辨率开始!", true);            //3. 获取分辨率            int[] ImageSize = iSEM.GetImageStore();            if (ImageSize[0] == 0 || ImageSize[1] == 0)            {                return false;            }            short width = (short)ImageSize[0];            short height = (short)ImageSize[1];            log.Info("获取分辨率结束!" + a_fileName + "====" + width + "*" + height, true);            //4. 抓图            if (!iSEM.GrabImage(a_fileName, 0, 0, width, height, 0))            {                log.Info("抓图失败!", true);                return false;            }            return true;        }                       //执行自动对焦        public bool ImageFocus1(Boolean Is_Stig)        {            if (MParam.FocusMode == 1)//手动            {                if (DialogResult.Yes == MessageBox.Show("图像自动对焦已完成?", "确认消息", MessageBoxButtons.YesNo))                {                }                else                {                    return false;                }            }            else if (MParam.FocusMode == 2)//自有自动            {                #region 执行蔡司自动对焦程序                //服务地址                string snumstr = @"http://192.168.1.101:8123";                bool normalized;                if (MParam.SampleName == "1")//第1大类代表3、4小类                {                    normalized = false;                }                else                {                    normalized = true;                }                // 调用方法;只对焦不消像散                if (Is_Stig)                {                    string focusstig = XmlRpcClient.autofocusstig(10, 3, 3, 3, 0.7, snumstr);//,normalized                    if (focusstig != "success")                    {                        log.Error("对焦失败" + focusstig, false);                        return false;                    }                }                else                {                    string onlyfocus = XmlRpcClient.autofocus(10, 3, 3, true, snumstr);//,normalized                    if (onlyfocus != "success")                    {                        return false;                    }                }                #endregion            }            else if (MParam.FocusMode == 3)     //客户自动            {                //后期和客户对接接口                List<string> filenames = new List<string>();                String retfilename = ImagePro.Img_Auto_Focus(filenames);            }            else        //蔡司自动对焦            {                iSEM.CmdAutoFocusCoarse();                while (true)                {                    Thread.Sleep(10000);                    if (0 == iSEM.GetAutoFunction())                    {                        break;                    }                }                iSEM.CmdAutoFocusFine();                while (true)                {                    Thread.Sleep(10000);                    if (0 == iSEM.GetAutoFunction())                    {                        break;                    }                }            }            return true;        }              //移动到像素位置,这里要靠移动样品台实现,当位移量小于3um时,不予移动        bool MoveToPixByMoveStage(float xc, float yc)        {            //单位是m/pix            float XpixSize = iSEM.GetPixelSize();            log.Info("X像素尺寸=" + XpixSize.ToString() + "m/pixel", true);            float YpixSize = iSEM.GetPixelSize();///(float)MParam.PixelSizeCor);            log.Info("Y像素尺寸=" + YpixSize.ToString() + "m/pixel", true);            Thread.Sleep(500);            //0:width, 1:height            int[] imageSize = iSEM.GetImageStore();            int width = imageSize[0] / 2;            int height = imageSize[1] / 2;            log.Info("目标像素是(" + xc.ToString() + "," + yc.ToString() + ")", true);            log.Info("中心像素是(" + width.ToString() + "," + height.ToString() + ")", true);            float deltX = (xc - (float)width) * XpixSize;            float deltY = (yc - (float)height) * YpixSize;            log.Info("x位移量 = " + deltX.ToString() + "m", true);            log.Info("y位移量 = " + deltY.ToString() + "m", true);            float xpCur = iSEM.GetStageAtX();            float ypCur = iSEM.GetStageAtY();            log.Info("当前位置(" + xpCur.ToString() + "," + ypCur.ToString() + "),单位m", true);            float xpNew = xpCur - deltX;            float ypNew = ypCur + deltY;            log.Info("目标位置(" + xpNew.ToString() + "," + ypNew.ToString() + "),单位m", true);            //计算光束偏移值:            //if (deltX >= 0.000003 || deltX <= 0.000003)//大于3um使用移动样品台实现            {                log.Info("X方向移动样品台", true);                if (!iSEM.SetStageGotoX(xpNew))                {                    return false;                }                //判断是否移动完成                while (true)                {                    Thread.Sleep(5000);                    if (iSEM.GetStageIs() == 0)                    {                        break;                    }                }            }            //if (deltY >= 0.000003 || deltY <= -0.000003)//大于3um使用移动样品台实现            {                log.Info("Y方向移动样品台", true);                if (!iSEM.SetStageGotoY(ypNew))                {                    return false;                }                //判断是否移动完成                while (true)                {                    Thread.Sleep(5000);                    if (iSEM.GetStageIs() == 0)                    {                        break;                    }                }            }            return true;        }        //移动到像素位置        bool MoveToPix(float xc, float yc)        {            //单位是m/pix            float XpixSize = iSEM.GetPixelSize();            log.Info("X像素尺寸=" + XpixSize.ToString() + "m/pixel", true);            float YpixSize = (XpixSize / (float)MParam.PixelSizeCor);            log.Info("Y像素尺寸=" + YpixSize.ToString() + "m/pixel", true);            Thread.Sleep(200);            //0:width, 1:height            int[] imageSize = iSEM.GetImageStore();            int width = imageSize[0] / 2;            int height = imageSize[1] / 2;            log.Info("目标像素是(" + xc.ToString() + "," + yc.ToString() + ")", true);            log.Info("中心像素是(" + width.ToString() + "," + height.ToString() + ")", true);            float deltX = (xc - (float)width) * XpixSize;            float deltY = (yc - (float)height) * YpixSize;            log.Info("x位移量 = " + deltX.ToString() + "m", true);            log.Info("y位移量 = " + deltY.ToString() + "m", true);            float xpCur = iSEM.GetStageAtX();            Thread.Sleep(200);            float ypCur = iSEM.GetStageAtY();            log.Info("当前位置(" + xpCur.ToString() + "," + ypCur.ToString() + "),单位m", true);            float xpNew = xpCur - deltX;            float ypNew = ypCur + deltY;            log.Info("目标位置(" + xpNew.ToString() + "," + ypNew.ToString() + "),单位m", true);            //计算最大偏移量            float beamXCur = iSEM.GetBeamShiftX();//单位是%            Thread.Sleep(200);            iSEM.SetBeamShiftX(100);            Thread.Sleep(200);            float beamXMax = iSEM.GetBeamOffsetX();//单位是m            Thread.Sleep(200);            iSEM.SetBeamShiftX(beamXCur);            Thread.Sleep(200);            //计算光束偏移值:            float beamX = iSEM.GetBeamOffsetX();            log.Info("当前X方向光束偏移量=" + beamX.ToString() + "m", true);            beamX = (-deltX + beamX);            log.Info("X方向光束偏移量应为=" + beamX.ToString() + "m", true);            if (((beamX <= beamXMax) && (beamX >= 0)) ||                ((beamX >= -beamXMax) && (beamX < 0)))            {                log.Info("X方向移动光束", true);                float beamXShift = beamX * 100 / beamXMax;                log.Info("X方向光束偏移量应为=" + beamXShift.ToString() + "%", true);                if (!iSEM.SetBeamShiftX(beamXShift))//if (!iSEM.SetBeamOffsetX(beamX))                {                    log.Info("X方向光束偏移量" + beamX.ToString() + "m失败", true);                    return false;                }            }            else if (deltX > 0.000003 || deltX < -0.000003)//大于3um使用移动样品台实现            {                log.Info("X方向移动样品台", true);                if (!iSEM.SetStageGotoX(xpNew))                {                    return false;                }                //判断是否移动完成                while (true)                {                    Thread.Sleep(4000);                    if (iSEM.GetStageIs() == 0)                    {                        break;                    }                }            }            float beamY = iSEM.GetBeamOffsetY();            log.Info("当前Y方向光束偏移量=" + beamY.ToString() + "m", true);            beamY = (-deltY + beamY);            log.Info("Y方向光束偏移量应为=" + beamY.ToString() + "m", true);            //计算最大偏移量            float beamYCur = iSEM.GetBeamShiftY();//单位是%            Thread.Sleep(200);            iSEM.SetBeamShiftY(100);            Thread.Sleep(200);            float beamYMax = iSEM.GetBeamOffsetY();//单位是m            Thread.Sleep(200);            iSEM.SetBeamShiftY(beamYCur);            Thread.Sleep(200);            if (((beamY <= beamYMax) && (beamY >= 0)) ||                ((beamY >= -beamYMax) && (beamY < 0)))            {                log.Info("Y方向移动光束", true);                float beamYShift = beamY * 100 / beamYMax;                log.Info("Y方向光束偏移量" + beamYShift.ToString() + "%", true);                //if(!iSEM.SetBeamOffsetY(beamY))                if (!iSEM.SetBeamShiftY(beamYShift))                {                    log.Info("Y方向光束偏移量" + beamY.ToString() + "m失败", true);                    return false;                }            }            else if (deltY > 0.000003 || deltY < -0.000003)//大于3um使用移动样品台实现            {                log.Info("Y方向移动样品台", true);                if (!iSEM.SetStageGotoY(ypNew))                {                    return false;                }                //判断是否移动完成                while (true)                {                    Thread.Sleep(4000);                    if (iSEM.GetStageIs() == 0)                    {                        break;                    }                }            }            return true;        }        #region 能谱所有参数        //全局只有一个Extender        static ExtenderInterface factoryExtender = ExtenderInterface.Instance;        public IExtenderControl iExtender = null;        const int ScanFieldSize = 1142;        MeasureDB m_MeasDB = null;        int m_nXrayId = 0;        const String ImageNameEDS = @"EDSImage.tif"; //EDS能谱图片        const String ImageNameEDS4 = @"SEMTrapCPEDS.tif";//传给客户,找到已经切割点        const String ImageNameEDS5 = @"SEMDegreeTrapEDS.tif";//传给客户,水平校正        const String ImageNameEDS6 = @"SEMMagEndEDS.tif";//传给客户,测量层高        /// <summary>        /// 做能谱分析        /// </summary>        /// <param name="a_CutHoleID">分析点视场ID,索引号</param>        /// <param name="a_CutHoleName">分析点视场名称</param>        /// <param name="a_FieldImagePositionID">分析点的视场位置ID,图像处理会返回多个Xray分析点,但我们这里只取第一个点所在的视场</param>        /// <returns>成功或失败</returns>        public bool DoEDS(int a_CutHoleID, string a_CutHoleName, int a_FieldImagePositionID)        {            try            {                //XrayID记录                log.Info("程序进入EDS测量!", true);                iExtender = factoryExtender.IExtender;                Thread.Sleep(500);                EDSParam param = MParam.EDSParam;                double dDwellTime = param.DwellTime;                int nImageType = param.ImageType;                double dScanSizes = param.ScanSize;                log.Info("dDwellTime=" + dDwellTime.ToString() + " nImageType=" + nImageType.ToString() + " dScanSizes=" + dScanSizes.ToString(), true);                iExtender.SetImageAcquistionSetting(dDwellTime, nImageType, dScanSizes);                string path = EDS_path;                string edsfn = path + "\\" + a_FieldImagePositionID.ToString() + "_" + ImageNameEDS;                log.Info("EDS_PATH=" + edsfn, true);                iExtender.GrabImage(edsfn, 0, 0, 0, 0, 0);//get the field eds image where the anylysis point locate.                arg.Picture_Information.Picture_FullPath = "";                arg.State = true;                SendMsg("4-5");//向界面发送指令:能谱拍照                //arg.State = false;                arg.Message = "";                arg.Picture_Information.Picture_FullPath = edsfn;                SendMsg("EDSPic");                //送给客户,计算感兴趣的区域                List<System.Drawing.Point> listPoints = new List<System.Drawing.Point>();                List<System.Drawing.Point> LinesStartPoint = new List<System.Drawing.Point>();                List<List<Segment>> listFeature = new List<List<Segment>>();                List<int> lines_height = new List<int>();                System.Drawing.Point area_pt = new System.Drawing.Point();                int width = 1;                int height = 1;                int AreasNo = 0;                long[] XrayData;                Dictionary<string, double> listElement;                int xrayCollectMode = param.XrayCollectMode;                switch (xrayCollectMode)                {                    case 0://point mode                           //点数据                        int state = 0;                        ImagePro.EDS_Param_Points(edsfn, a_FieldImagePositionID, Convert.ToInt32(MParam.SampleName), MParam.Firm, out listPoints, out state);                        if (state == 0)                        {                            log.Error("点采集失败", false);                            return false;                        }                        log.Info("返回 listPoints=" + listPoints.Count.ToString(), true);                        if (!m_MeasDB.InsertAnylysisField(a_CutHoleID, a_CutHoleName, EDS_path, listPoints.Count, listFeature.Count, a_FieldImagePositionID))                        {                            log.Error("插入分析视场失败", false);                        }                        iExtender.BeginMultipleAquisition();                        Thread.Sleep(100);                        //点采集                        m_nXrayId = 0;                        foreach (System.Drawing.Point pt in listPoints)                        {                            XrayData = new long[2000];                            listElement = new Dictionary<string, double>();                                                      if (iExtender.XrayPointCollecting(param.PointTime, pt.X, pt.Y , out XrayData, out listElement))                            {                                string ele = "";                                foreach (var s in listElement)                                {                                    ele += s.ToString();                                }                                log.Info("采集点:(" + pt.X.ToString() + ":" + pt.Y.ToString() + ") 元素:" + ele);                                //写入数据库                                m_nXrayId++;                                log.Info("点采集结束,写入数据库开始--" + m_nXrayId.ToString(), true);                                Boolean ret = m_MeasDB.InsertAPointXray(a_CutHoleID, m_nXrayId, pt.X, pt.Y, XrayData, listElement, a_FieldImagePositionID);                                Thread.Sleep(1000);                            }                        }                        iExtender.EndMultipleAquisition();                        break;                    case 1://line mode                        log.Info("线扫描", true);                        state = 0;                        ImagePro.EDS_Param_Lines(edsfn, a_FieldImagePositionID, Convert.ToInt32(MParam.SampleName), MParam.Firm, out LinesStartPoint, out lines_height, out state);                        string sp = "";                        foreach (System.Drawing.Point p in LinesStartPoint)                        {                            sp += "(" + p.X + "," + p.Y + ")";                        }                        log.Info("线返回数据,lines=" + LinesStartPoint.Count.ToString() + " " + sp, true);                        if (state == 1)                        {                            //将线转换为segment数据                            log.Info("将线转换为segment数据", true);                                                       for (int i = 0; i < LinesStartPoint.Count; i++)                            {                                                               List<Segment> segments = new List<Segment>();                                for (int j = 0; j <= lines_height[i]; j++)                                {                                    Segment segment = new Segment();                                    segment.X = LinesStartPoint[i].X;                                    segment.Y = LinesStartPoint[i].Y + j;                                    segment.Length = 2;                                    segments.Add(segment);                                }                                listFeature.Add(segments);                            }                        }                        else                        {                            log.Error("线扫图片处理失败", false);                            return false;                        }                        //线采集                        iExtender.BeginMultipleAquisition();                        Thread.Sleep(100);                        for (int i = 0; i < listFeature.Count; i++)                        {                            List<Segment> listSeg = listFeature[i];                            XrayData = new long[2000];                            listElement = new Dictionary<string, double>();                            if (iExtender.XrayAreaCollectiong(param.AreaTime, listSeg, out XrayData, out listElement))                            {                                string ele = "";                                foreach (var s in listElement)                                {                                    ele += s.ToString();                                }                                log.Info("采集时间=" + param.AreaTime.ToString(), true);                                log.Info("(" + listSeg[0].X + "," + listSeg[0].Y + ") height=" + lines_height[i] + " 元素:" + ele);                                log.Info("线采集结束,写入数据库开始", true);                                //写入数据库                                m_nXrayId++;                                AreasNo++;                                m_MeasDB.InsertAAreaXay(a_CutHoleID, m_nXrayId, AreasNo, listSeg, XrayData, listElement, a_FieldImagePositionID);                            }                            else                            {                                log.Error("线扫xray失败");                            }                        }                        iExtender.EndMultipleAquisition();                        break;                    case 2: //area mode                            //面数据                        state = 0;                        ImagePro.EDS_Param_Areas(edsfn, a_FieldImagePositionID, Convert.ToInt32(MParam.SampleName), MParam.Firm, out area_pt, out width, out height, out state);                        log.Info("面返回数据" + area_pt.X.ToString() + "," + area_pt.Y.ToString() + ",height=" + height.ToString() + ",width=" + width.ToString(), true);                        if (state == 1)                        {                            //将面转换为segment数据                            List<Segment> segments = new List<Segment>();                            for (int j = 0; j <= height; j++)                            {                                Segment segment = new Segment();                                segment.X = area_pt.X;                                segment.Y = area_pt.Y + j;                                segment.Length = width;                                segments.Add(segment);                            }                            listFeature.Add(segments);                        }                        else                        {                            log.Error("面扫图片处理失败", false);                            return false;                        }                        //面采集                        iExtender.BeginMultipleAquisition();                        Thread.Sleep(100);                        foreach (List<Segment> listSeg in listFeature)                        {                            XrayData = new long[2000];                            listElement = new Dictionary<string, double>();                            log.Info("AreaTime=" + param.AreaTime.ToString(), true);                            if (iExtender.XrayAreaCollectiong(param.AreaTime, listSeg, out XrayData, out listElement))                            {                                string ele = "";                                foreach (var s in listElement)                                {                                    ele += s.ToString();                                }                                log.Info(" 元素:" + ele);                                log.Info("面采集结束,写入数据库开始", true);                                //写入数据库                                m_nXrayId++;                                AreasNo++;                                m_MeasDB.InsertAAreaXay(a_CutHoleID, m_nXrayId, AreasNo, listSeg, XrayData, listElement, a_FieldImagePositionID);                            }                            else                            {                                log.Error("面扫xray失败");                            }                        }                        iExtender.EndMultipleAquisition();                        break;                }                //存储数据                //向分析点数据库更新            }            catch (Exception e)            {                iExtender.EndMultipleAquisition();                log.Error(e.Message, false);                return false;            }            return true;        }        /// <summary>        /// 初始化数据库        /// </summary>        public void Init_MeasDB()        {            m_MeasDB = new MeasureDB(m_measureFile);        }        /// <summary>        /// 161.自动调整SEM找到切割位置,这里不是简单的拉直旋转        /// </summary>        /// <returns></returns>        public bool EDS_FindCross()        {            float x2 = 0, y2 = 0;            int state = 0;            float mag = MParam.Photograph_Magnification / 3;                       String fileName4 = data_path + "\\" + MParam.Firm + "-" + mag.ToString("0") + "-" + m_cutHoles[m_nWorkHoleNo].HoleName + "-" + ImageNameEDS4;            PhotoParam prm = new PhotoParam()            {                            Mag = mag,                savePath = fileName4,                scanSpeed= MParam.ScanSpeedHigh,                scanSpeedAfter=MParam.ScanSpeedNormal,                                              };            Photo pho = new Photo(prm,iSEM);            pho.TakePhoto();                 arg.Picture_Information.Picture_FullPath = fileName4;            arg.Picture_Information.Work_Voltage = iSEM.GetSEMVoltage();            //Thread.Sleep(200);            arg.Picture_Information.Magnification = iSEM.GetMagnification();            //Thread.Sleep(200);            arg.Picture_Information.Work_Distance = iSEM.GetWorkingDistance();            //Thread.Sleep(200);            SendMsg("4-2");            //拍照前改变速度,延时            if (key_stop)            {                return false;            }            //4.将照片传给客户,获取偏移坐标,以及偏移角度            //5.根据坐标控制SEM移动到切孔位置,居中            log.Info("测量线程:图像处理接口,准备移动样品台", true);            log.Info("文件名=" + fileName4, true);            ImagePro.Img_Trapezoid_Top_Center_Position(fileName4, Convert.ToInt32(MParam.SampleName), MParam.Firm, out x2, out y2, out state);                       log.Info("梯形中心点返回数据=" + x2.ToString() + ", " + y2.ToString(), true);            log.Info("准备移动样品台返回状态=" + state.ToString(), true);            if (state == 1)            {                LocateParam lprm = new LocateParam()                {                    PositionX = x2,                    PositionY = y2,                    PixelSize_Y_cur = MParam.PixelSizeCor ,                                    };                Locate loc = new Locate(lprm, iSEM);                //1. 根据客户PT沉积坐标控制FIB调整到中心位置???????                if (!loc.DoLocateByMoveStage())                {                    log.Error("测量线程报错:" + arg.Message, false);                    return false;                }                          }            else            {                arg.Message = "图像接口参数state返回值为零";                arg.State = false;                //SendMsg("3-3");                if (hand_intervene == 1)                {                    if (DialogResult.Yes != MessageBox.Show("网络参数State返回为0。\n是否继续操作?。", "确认消息", MessageBoxButtons.YesNo))                    {                        return false;                    }                }                else                {                    return false;                }                log.Error("测量线程报错:" + arg.Message, false);                return false;            }            //判断是否停止进程            if (key_stop)            {                log.Info("停止键按下", true);                return false;            }                        return true;        }        /// <summary>        /// 171.能谱第17步找点采集数据        /// </summary>        /// <returns></returns>        public bool EDS_ShotSection()        {            int state = 0;                                   log.Info("设置拍照放大倍数=" + MParam.Photograph_Magnification.ToString(), true);            Focusparam fprm = new Focusparam()            {                mag = MParam.Photograph_Magnification,                reduceWindowPos = new System.Drawing.Point(402, 128),                reduceWinHeight = 600,                reduceWinWidth = 600,                ScanSpeed = MParam.ScanSpeedFocus,                IfAutoBrightnessAndContrast = true,                delayTime = 500,                voltage = 7000,                Iprobe = 0.5f,                workingDis = 10,//unit mm                brightness = 50,                contrast = 29,                tiltCorrAngle = 36,            };                                                   log.Info("自动对焦开始!", true);            Focus f = new Focus(fprm, iSEM);            f.DoFocus();            SendMsg("4-4");                      //add by zjx 2020-12-21 根据客户的需求修改图片的名称            String fileName5 = data_path + "\\EDS\\" + MParam.Firm + "-" + MParam.Photograph_Magnification.ToString("0") + "-" + m_cutHoles[m_nWorkHoleNo].HoleName + "-" + ImageName5;            //add by zjx 2020-12-21 根据客户的需求修改图片的名称 end             log.Info("fileName5=" + fileName5, true);                      log.Info("开始拍摄截面照!");            PhotoParam phoPrm = new PhotoParam()            {                Mag = MParam.Photograph_Magnification,                savePath = fileName5,                scanSpeed = MParam.ScanSpeedHigh,                scanSpeedAfter = MParam.ScanSpeedNormal,            };            Photo pho = new Photo(phoPrm, iSEM);            pho.TakePhoto();            //判断是否停止进程            if (key_stop)            {                log.Info("停止键按下", true);                return false;            }            #endregion            if (MParam.Is_Photograph == false)//Is_Photograph 代表 是否是只拍照            {                #region 对当前矩形进行旋转校正                //8,计算切割面区域偏移角度及方向                float degree = 0;                int direction = 0;                ImagePro.Img_Center_Position_OffsetAngle_Direction(fileName5, Convert.ToInt32(MParam.SampleName), MParam.Firm, out degree, out direction, out state);                log.Info("测量线程:2000倍===拍照角度移动,输入图像" + fileName5 + "输出角度为" + degree.ToString() + "输出方向为" + direction.ToString() + "返回值为" + state.ToString(), true);                log.Info("样品" + m_nWorkHoleNo.ToString() + "计算切割面区域的角度=" + degree.ToString(), true);                //接口返回像素,*pixelsize,得到坐标点。判断移动方式                if (state == 1)                {                    //梯形角度                    iSEM.SetScanRotationOn();                    Thread.Sleep(200);                    //20201128陈工要求,谭博返回角度*0.7                    iSEM.SetScanRotation(Convert.ToSingle(degree * 0.7));                    Thread.Sleep(200);                    arg.State = true;                    arg.Message = "图像接口返回角度为:" + degree.ToString();                    log.Info(arg.Message);                                  }                else                {                    arg.Message = "图像接口参数State返回值为零";                                                                            log.Error("测量线程报错:" + arg.Message, false);                }                //判断是否停止进程                if (key_stop)                {                    log.Info("停止键按下", true);                    return false;                }                Thread.Sleep(200);                //add by zjx 2020-12-21 根据客户的需求修改图片的名称                String fileName6 = data_path + "\\EDS\\" + MParam.Firm + "-" + MParam.Photograph_Magnification.ToString("0") + "-" + m_cutHoles[m_nWorkHoleNo].HoleName + "-" + ImageName6;                //add by zjx 2020-12-21 根据客户的需求修改图片的名称 end                 log.Info("fileName6=" + fileName6, true);                log.Info("纠正后拍照!");                PhotoParam phoprm = new PhotoParam()                {                    Mag = MParam.Photograph_Magnification,                    scanSpeed = MParam.ScanSpeedHigh,                    scanSpeedAfter = MParam.ScanSpeedNormal,                       savePath=fileName6,                };                Photo pho1 = new Photo(phoprm, iSEM);                pho1.TakePhoto();                               if (key_stop)                {                    log.Info("停止键按下", true);                    return false;                }                #endregion                #region 获取两个位置上及放大倍数                //计算两个测量区域坐标                List<System.Drawing.Point> ct = new List<System.Drawing.Point>();                List<float> mag = new List<float>();                System.Drawing.Point ct0;                float mag1, mag2, magMax;                log.Info("图像处理接口,计算两个放大区域坐标,输入图像" + fileName6.ToString(), true);                ImagePro.Img_Measure_Region_Position(fileName6, Convert.ToInt32(MParam.SampleName), MParam.Firm, out ct, out mag, out ct0, out state);                string s = "";                for (int i = 0; i < ct.Count; i++)                {                    s += "输出观测点" + i.ToString() + "为(" + ct[i].X.ToString() + "," + ct[i].Y.ToString() + ")"                    + "放大倍数=" + mag[i];                }                log.Info("测量线程:图像处理接口返回值为" + state.ToString() +                    ",计算两个放大区域坐标,输入图像" + fileName6.ToString() +                    "输入样品" + Convert.ToInt32(MParam.SampleName) +                    "输入厂商" + MParam.Firm.ToString() +                    s +                  "输出对焦点为(" + ct0.X.ToString() + "," + ct0.Y.ToString() + ")", true);                #endregion                if (state == 1 && ct.Count != 0 && mag.Count != 0)                {                    Locate recordPostion = new Locate(iSEM);                    recordPostion.RecordCurrentBeamShiftAndStagePosition();                    //找到放大倍数最大值                    magMax = mag[0];                    for (int m = 1; m < mag.Count; m++)                    {                        if (mag[m] > magMax)                        {                            magMax = mag[m];                        }                    }                    #region 移动到梯形左上角                    //20201127将视野移动到梯形左上角位置                    log.Warn("开始对焦 移动到对焦点( " + ct0.X.ToString()                        + "," + ct0.Y.ToString() + ")", true);                    //MoveToPix(ct0.X, ct0.Y);                    LocateParam lprm = new LocateParam()                    {                        PositionX = ct0.X,                        PositionY = ct0.Y,                        PixelSize_Y_cur = MParam.PixelSizeCor ,                    };                    Locate loc = new Locate(lprm, iSEM);                    loc.DoLocateByShiftBeam();                    Focusparam fprm1 = new Focusparam()                    {                        mag = magMax / 4,                        reduceWindowPos = new System.Drawing.Point(402, 128),                        reduceWinHeight = 600,                        reduceWinWidth = 600,                        ScanSpeed = MParam.ScanSpeedFocus,                        IfAutoBrightnessAndContrast = false,                        delayTime = 500,                        voltage = 7000,                        Iprobe = 0.5f,                        workingDis = 10 ,                        brightness = 49.4f,                        contrast = 30.1f,                         tiltCorrAngle =36,                    };                                                                                                              log.Info("自动对焦1开始!", true);                    Focus f1 = new Focus(fprm1, iSEM);                    f1.DoFocus();                    log.Info("自动对焦2开始!", true);                    f1.DoFocusByNewMagnification(magMax / 2);                    #endregion                    log.Warn("对焦完成,开始用能谱拍摄观测点照片!并分析图片以获得Xray点位置!");                    recordPostion.RestoreLastBeamShiftAndStagePosition();                    log.Warn("移动到指定观测点!并准备打Xray");                    LocateParam locp = new LocateParam()                    {                        PositionX=ct[0].X ,                        PositionY=ct[0].Y,                         PixelSize_Y_cur =MParam.PixelSizeCor ,                    };                    Locate loc2 = new Locate(locp, iSEM);                    loc2.DoLocateByShiftBeam();                    SendMsg("4-4");//向界面发送指令:放大并对拍摄点对焦                    //#endregion                    Thread.Sleep(200);                //add by sun 2020-12-17 根据客户要求,3大类样品需要在5000倍下在拍摄一张图片,不需要分析 end                #region 拍照                log.Info("进入内部观察,不对焦!", true);                log.Info("开始拍照,设置放大倍数" + mag[0]);                if (!iSEM.SetMagnification(mag[0]))                {                    log.Error("设置放大倍数失败", false);                    return false;                }                Thread.Sleep(300 + Convert.ToInt32(cycle_time));                                            //add by zjx 2020-12-21 根据客户的需求修改图片的名称                String fileName7 = data_path + "\\EDS\\" + MParam.Firm + "-" + mag[0].ToString() + "-" + m_cutHoles[m_nWorkHoleNo].HoleName + "-0-" + ImageNameTwo_1;                //add by zjx 2020-12-21 根据客户的需求修改图片的名称 end                 log.Info("fileName7=" + fileName7, true);                arg.Picture_Information.Picture_FullPath = fileName7;                arg.Picture_Information.Work_Status = "SEM";                arg.Picture_Information.Work_Voltage = iSEM.GetSEMVoltage();                Thread.Sleep(200);                arg.Picture_Information.Magnification = iSEM.GetMagnification();                Thread.Sleep(200);                arg.Picture_Information.Work_Distance = iSEM.GetWorkingDistance();                Thread.Sleep(200);                //拍照前改变速度,延时                iSEM.CmdLineScan();                Thread.Sleep(200);                cycle_time = iSEM.GetCycleTime();                Thread.Sleep(Convert.ToInt32(cycle_time) + 100);                                log.Warn("EDS获取指定观测点图片,并打Xray");                DoEDS(m_nWorkHoleNo, m_cutHoles[m_nWorkHoleNo].HoleName, 1);                log.Info("像素扫描:CmdPixelScan");                iSEM.CmdPixelScan();                Thread.Sleep(200);                log.Info("改变刷新率 " + MParam.ScanSpeedNormal);                iSEM.CmdFocusScanSpeed(MParam.ScanSpeedNormal);//CmdFocusRate(4);                Thread.Sleep(200);                cycle_time = iSEM.GetCycleTime();                Thread.Sleep(Convert.ToInt32(cycle_time) + 100);                SendMsg("4-6");//向界面发生指令:采集能谱信息                }                #endregion            }            iSEM.SetTiltAngleOff();            Thread.Sleep(200);            iSEM.SetScanRotationOff();            Thread.Sleep(200);            iSEM.SetBeamShiftX(0);            Thread.Sleep(200);            iSEM.SetBeamShiftY(0);            Thread.Sleep(200);            //判断是否停止进程            return true;        }        /// <summary>        /// 19.能谱分析        /// </summary>        /// <returns></returns>        public bool EDS_Analysis()        {            //1.先降Z轴  37.241左右使工作距离从5mm 变为 10mm,这样方便能谱工作,麻烦是需要从新对焦。由于移动样品台会有误差,容易造成图像偏移,最好从新定位            Locate lo = new Locate(iSEM);                        lo.MoveZAxisByAbs(MParam.EDSZ);                      //判断是否停止进程            if (key_stop)            {                log.Info("停止键按下", true);                return false;            }            SendMsg("4-0");                       //2.角度改为54度            iSEM.SetScanRotationOff();            Thread.Sleep(200);            Focusparam focusPrm = new Focusparam()            {                voltage = 7000,                Iprobe = 0.5F,                IfAutoBrightnessAndContrast = true,                ScanSpeed = MParam.ScanSpeedHigh,                mag = 600,                reduceWindowPos = new System.Drawing.Point(256, 192),                reduceWinWidth = 400,                reduceWinHeight = 400,                workingDis = 10,//unit:mm                brightness = 50,                contrast = 29,                tiltCorrAngle =54,                             };                      Focus f = new Focus(focusPrm, iSEM);            f.DoFocus();            SendMsg("4-1");            log.Warn("开始梯形移到视野中心!");                       if (!EDS_FindCross())            {                return false;            }            SendMsg("4-3");            //7.调用171步过程            log.Warn("开始打能谱图和打Xray!");            if (!EDS_ShotSection())            {                return false;            }            return true;        }        /// <summary>        /// 20.光束等复位        /// </summary>        public void BeamShiftReset()        {            iSEM.SetTiltAngleOff();            Thread.Sleep(200);            iSEM.SetScanRotationOff();            Thread.Sleep(200);            iSEM.SetBeamShiftX(0);            Thread.Sleep(200);            iSEM.SetBeamShiftY(0);            Thread.Sleep(200);        }        //add by sun 2020-12-17 不同样品电压、电流不一致,应设置灵活。123456类电压2000V电流200pA,7类5000V 500pA,能谱 7000V 500pA        #region 设置电压电流        public bool SetVoltageAndIPROBE()        {            log.Info("测量线程:设置电压电流 123456类电压2000V电流200pA,7类5000V 500pA,能谱 7000V 500pA  目前是第 " + MParam.SampleName + " 类!", true);            //这块应该做成参数!!! 暂时写死。类型3 则为 5000V 500pA            bool mRet_VoltageFlag = false;            bool mRet_ElecFlag = false;            if (MParam.SampleName == "4" || MParam.SampleName == "5")            {                mRet_VoltageFlag = iSEM.SetSEMVoltage(5000);                Thread.Sleep(500);                mRet_ElecFlag = iSEM.SetSEMIPROBE(0.2F / 1000000000);                Thread.Sleep(500);            }            else if (MParam.SampleName == "3")            {                mRet_VoltageFlag = iSEM.SetSEMVoltage(5000);                Thread.Sleep(500);                mRet_ElecFlag = iSEM.SetSEMIPROBE(0.5F / 1000000000);                Thread.Sleep(500);            }            else            {                              mRet_VoltageFlag = iSEM.SetSEMVoltage(2000);                Thread.Sleep(500);                mRet_ElecFlag = iSEM.SetSEMIPROBE(0.2F / 1000000000);                Thread.Sleep(500);            }            if (!mRet_VoltageFlag) return false;            if (!mRet_ElecFlag) return false;            log.Info("测量线程:设置电压电流完成!", true);            return true;        }        #endregion        //add by sun 2020-12-17 不同样品电压、电流不一致,应设置灵活。123456类电压2000V电流200pA,7类5000V 500pA,能谱 7000V 500pA end        //add by sun 2020-12-17 根据客户要求,3大类样品需要在5000倍下在拍摄一张图片,不需要分析             //add by sun 2020-12-17 根据客户要求,3大类样品需要在5000倍下在拍摄一张图片,不需要分析 end        //add by zjx 2020-12-21 在测量图上显示放大倍数和像素大小等信息        public void SaveMeasDataPic(String picFullPath, float Mag, float pixelsize)        {            try            {                using (System.Drawing.Image img = Image.FromFile(picFullPath))                {                    Bitmap bmp = new Bitmap(img.Width, img.Height);                    using (Graphics g = Graphics.FromImage(bmp))                    {                        g.DrawImage(img, 0, 0, img.Width, img.Height);                        String str = "Mag:" + Mag.ToString("0") + "X\tPixelSize:" + (pixelsize * 1000000).ToString("0.00") + "um";                        Font font = new Font("宋体", 16, FontStyle.Bold);                        SolidBrush sbrush = new SolidBrush(Color.LimeGreen);                        g.DrawString(str, font, sbrush, new PointF(40, img.Height - 30));                    }                    System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);                    Bitmap newBitmap = new Bitmap(img.Width, img.Height, bmpData.Stride, System.Drawing.Imaging.PixelFormat.Format8bppIndexed, bmpData.Scan0);                    String path = Path.GetDirectoryName(picFullPath) +                        Path.GetFileNameWithoutExtension(picFullPath) +                        "_Data" + Path.GetExtension(picFullPath);                    newBitmap.SetResolution(1, 1);                    newBitmap.Save(path);                }            }            catch            {                log.Error("在测量图上显示放大倍数和像素大小信息失败", false);            }        }        //add by zjx 2020-12-21 在测量图上显示放大倍数和像素大小等信息 end    }}
 |