00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "app_peakfind.h"
00030
00031 #include "gxsm/regress.h"
00032 #include "gxsm/scan.h"
00033 #include "gxsm/dataio.h"
00034
00035 #include "gxsm/surface.h"
00036 #include "gxsm/glbvars.h"
00037 #include "gxsm/xsmtypes.h"
00038
00039 #include "gxsm/action_id.h"
00040
00041
00042
00043 #define L_NULL 0
00044 #define L_START 1
00045 #define L_MOVE 2
00046 #define L_END 3
00047
00048 #define QSIZE 5 // Size of Line-Handles (Squares)
00049 #define QSIZE1 QSIZE // Anfang
00050 #define QSIZE2 (QSIZE-2) // Ende
00051
00052 PeakFindScan::PeakFindScan()
00053 :Scan(ID_CH_V_NO, SCAN_V_DIRECT, -1, NULL, ZD_FLOAT){
00054 PI_DEBUG (DBG_L2, "PeakFindScan::PeakFindScan");
00055 StopPeakFindFlg=TRUE;
00056 data.Xunit = new UnitObj("s","t","g","time");
00057 data.Zunit = new UnitObj("CPS","CPS","g","Rate");
00058 data.LoadValues(NULL, NULL, "SPA_PeakFind_Set");
00059 data.s.dz = 1.;
00060 data.s.dx = 1.;
00061 data.s.dy = 1.;
00062 data.s.rx = 1.;
00063 data.s.ry = 1.;
00064 data.s.x0 = 0.;
00065 data.s.y0 = 0.;
00066 data.s.nx = 0;
00067 data.s.ny = 0;
00068 }
00069
00070 PeakFindScan::~PeakFindScan(){
00071 PI_DEBUG (DBG_L2, "PeakFindScan::~PeakFindScan" );
00072 data.SaveValues("SPA_PeakFind_Set");
00073 if(data.Xunit) delete data.Xunit;
00074 if(data.Zunit) delete data.Zunit;
00075 PI_DEBUG (DBG_L2, "done." );
00076 }
00077
00078 int PeakFindScan::Save(gchar *fname){
00079 const char *ret;
00080 Dataio *Dio;
00081 if(!strncasecmp(fname+strlen(fname)-3,".nc",3))
00082 Dio = new NetCDF(this, fname);
00083 else
00084 Dio = new DatFile(this, fname);
00085
00086 Dio->Write();
00087 ret = Dio->ioStatus();
00088 delete Dio;
00089 return(ret?1:0);
00090 }
00091
00092 int PeakFindScan::Load(gchar *fname){
00093 const char *ret;
00094 Dataio *Dio;
00095
00096 if(!strncasecmp(fname+strlen(fname)-3,".nc",3))
00097 Dio = new NetCDF(this, fname);
00098 else
00099 Dio = new DatFile(this, fname);
00100
00101 Dio->Read();
00102 ret = Dio->ioStatus();
00103 delete Dio;
00104 return(ret?1:0);
00105 }
00106
00107 int PeakFindScan::PFrun(XSM_Hardware *hw, SPA_PeakFind_p *pfp){
00108 PI_DEBUG (DBG_L2, "ProbeScan::Probe PF start");
00109
00110 if(!pfp){
00111 PI_DEBUG (DBG_L2, "ProbeScan::Probe PF start ERROR pfp object is a zero pointer");
00112 return -1;
00113 }
00114
00115 PFhwrun(hw, pfp);
00116
00117 #ifdef COPY_PFSCANS_TO_PROFILEVIEW
00118 data.s.nx = pfp->npkte;
00119 data.s.ny = 4;
00120 mem2d->Resize(data.s.nx, data.s.ny);
00121 mem2d->data->MkXLookup( -(double)pfp->npkte/2., (double)pfp->npkte/2. );
00122 data.s.tStart=time(0);
00123
00124 for(int i=0; i<data.s.ny; ++i)
00125 for(int j=0; j<data.s.nx; ++j){
00126 mem2d->PutDataPkt(pfp->xyscans->GetDataPkt(j,i),j,i);
00127 }
00128
00129 data.s.tEnd=time(0);
00130 PI_DEBUG (DBG_L2, "ProbeScan::Probe SetVM");
00131 if(!view)
00132 SetView(ID_CH_V_PROFILE);
00133 else
00134 draw();
00135 #endif
00136
00137 return 0;
00138 }
00139
00140 int PeakFindScan::PFrunI0(XSM_Hardware *hw, SPA_PeakFind_p *pfp){
00141 PI_DEBUG (DBG_L2, "ProbeScan::Probe PF start");
00142
00143 if(!pfp){
00144 PI_DEBUG (DBG_L2, "ProbeScan::Probe PF start ERROR pfp object is a zero pointer");
00145 return -1;
00146 }
00147
00148 PFhwrun(hw, pfp);
00149
00150 data.s.nx = pfp->count+1;
00151 data.s.ny = max(mem2d->GetNy(), (pfp->index+1));
00152
00153 mem2d->Resize(data.s.nx, data.s.ny);
00154 if(pfp->count==0 && pfp->index==0){
00155 data.s.tStart=time(0);
00156 data.s.x0 = 0.;
00157 data.s.y0 = 0.;
00158 data.s.rx = 0.;
00159 data.s.ry = 0.;
00160 data.s.alpha = 0.;
00161 data.s.dz = 1.;
00162 }
00163
00164 double cps;
00165 cps = (pfp->xyscans->GetDataPkt(pfp->npkte/2,0)
00166 + pfp->xyscans->GetDataPkt(pfp->npkte/2-1,0)
00167 + pfp->xyscans->GetDataPkt(pfp->npkte/2-2,0)
00168 + pfp->xyscans->GetDataPkt(pfp->npkte/2+1,0)
00169 + pfp->xyscans->GetDataPkt(pfp->npkte/2+2,0)
00170 + pfp->xyscans->GetDataPkt(pfp->npkte/2,1)
00171 + pfp->xyscans->GetDataPkt(pfp->npkte/2-1,1)
00172 + pfp->xyscans->GetDataPkt(pfp->npkte/2-2,1)
00173 + pfp->xyscans->GetDataPkt(pfp->npkte/2+1,1)
00174 + pfp->xyscans->GetDataPkt(pfp->npkte/2+2,1))
00175 / 10. / pfp->gate;
00176
00177
00178 gchar *datastr=g_strdup_printf("Pf%d Xscan: %10.1f %10.1f %6.3f %6.3f",
00179 pfp->index, pfp->I0x, pfp->xI0, pfp->xxf0, pfp->xfwhm);
00180 gapp->monitorcontrol->LogEvent("*ProbePFn", datastr);
00181 g_free(datastr);
00182
00183 datastr=g_strdup_printf("Pf%d Yscan: %10.1f %10.1f %6.3f %6.3f",
00184 pfp->index, pfp->I0y, pfp->yI0, pfp->yxf0, pfp->yfwhm);
00185 gapp->monitorcontrol->LogEvent("*ProbePFn", datastr);
00186 g_free(datastr);
00187
00188 datastr=g_strdup_printf("Pf%d Rate: %10.1f CPS", pfp->index, cps);
00189 gapp->monitorcontrol->LogEvent("*ProbePFn", datastr);
00190 g_free(datastr);
00191
00192
00193 mem2d->PutDataPkt(cps, pfp->count, pfp->index);
00194
00195
00196 if(pfp->index == 0){
00197
00198 data.s.tEnd = time(0);
00199 data.s.rx = (double)(data.s.tEnd - data.s.tStart);
00200 data.s.dl = data.s.rx;
00201 mem2d->data->MkXLookup( 0., data.s.rx);
00202 mem2d->data->MkYLookup( 1., (double)mem2d->GetNy());
00203
00204 if(pfp->count > 1){
00205 if(!view)
00206 SetView(ID_CH_V_PROFILE);
00207 else
00208 draw();
00209 }
00210 }
00211
00212 ++pfp->count;
00213
00214 return 0;
00215 }
00216
00217 int PeakFindScan::PFhwrun(XSM_Hardware *hw, SPA_PeakFind_p *pfp){
00218 PI_DEBUG (DBG_L2, "PeakFindScan::PeakFind");
00219 if(!pfp){
00220 PI_DEBUG (DBG_L2, "PeakFindScan::PeakFind PeakFind start ERROR pfp object is a zero pointer");
00221 return -1;
00222 }
00223 if(!pfp->Mode()) return -1;
00224
00225 PARAMETER_SET hardpar;
00226 size_t elem_size=sizeof(long);
00227 static long linebuffer[DSP_DATA_REG_LEN];
00228
00229 int wdh=pfp->maxloops;
00230
00231 pfp->x0 = pfp->xorg;
00232 pfp->y0 = pfp->yorg;
00233 pfp->Resize();
00234
00235 while(wdh--){
00236
00237 hardpar.N = DSP_E+1;
00238 hardpar.Cmd = DSP_CMD_SCAN_PARAM;
00239
00240 hardpar.hp[DSP_X0 ].value = (double)gapp->xsm->Inst->YA2Dig(pfp->x0);
00241 hardpar.hp[DSP_Y0 ].value = (double)gapp->xsm->Inst->YA2Dig(pfp->y0);
00242 hardpar.hp[DSP_len ].value = (double)gapp->xsm->Inst->YA2Dig(pfp->radius*2.);
00243 hardpar.hp[DSP_N ].value = pfp->npkte;
00244 hardpar.hp[DSP_alpha].value = 0.;
00245 hardpar.hp[DSP_ms ].value = 1e3*pfp->gate;
00246 hardpar.hp[DSP_E ].value = (double)gapp->xsm->Inst->eV2V(pfp->energy);
00247 hw->SetParameter(hardpar);
00248
00249 hardpar.N = DSP_E+1;
00250 hardpar.Cmd = DSP_CMD_SCAN_START;
00251 hardpar.hp[DSP_Y0 ].value = 0.;
00252 hardpar.hp[DSP_len ].value = (double)gapp->xsm->Inst->YA2Dig(pfp->radius*2.);
00253 hardpar.hp[DSP_E ].value = (double)gapp->xsm->Inst->eV2V(pfp->energy);
00254 hw->SetParameter(hardpar, TRUE);
00255
00256 hw->ReadData(linebuffer, pfp->npkte*elem_size);
00257
00258 for(int i=0; i<pfp->npkte; ++i)
00259 pfp->xyscans->PutDataPkt((double)linebuffer[i], i,0);
00260
00261
00262
00263 hardpar.N = DSP_E+1;
00264 hardpar.Cmd = DSP_CMD_SCAN_PARAM;
00265 hardpar.hp[DSP_X0 ].value = (double)gapp->xsm->Inst->YA2Dig(pfp->x0);
00266 hardpar.hp[DSP_Y0 ].value = (double)gapp->xsm->Inst->YA2Dig(pfp->y0);
00267 hardpar.hp[DSP_len ].value = (double)gapp->xsm->Inst->YA2Dig(pfp->radius*2.);
00268 hardpar.hp[DSP_N ].value = pfp->npkte;
00269 hardpar.hp[DSP_alpha].value = 90.;
00270 hardpar.hp[DSP_ms ].value = 1e3*pfp->gate;
00271 hardpar.hp[DSP_E ].value = (double)gapp->xsm->Inst->eV2V(pfp->energy);
00272 hw->SetParameter(hardpar);
00273
00274 hardpar.N = DSP_E+1;
00275 hardpar.Cmd = DSP_CMD_SCAN_START;
00276 hardpar.hp[DSP_Y0 ].value = 0.;
00277 hardpar.hp[DSP_len ].value = (double)gapp->xsm->Inst->YA2Dig(pfp->radius*2.);
00278 hardpar.hp[DSP_E ].value = (double)gapp->xsm->Inst->eV2V(pfp->energy);
00279 hw->SetParameter(hardpar, TRUE);
00280
00281 hw->ReadData(linebuffer, pfp->npkte*elem_size);
00282
00283 for(int i=0; i<pfp->npkte; ++i)
00284 pfp->xyscans->PutDataPkt((double)linebuffer[i], i,1);
00285
00286
00287 pfp->DoFit();
00288
00289
00290
00291
00292
00293 pfp->x0 = pfp->xnew;
00294 pfp->y0 = pfp->ynew;
00295
00296 if(fabs(pfp->shift) < pfp->konvfac) break;
00297
00298 }
00299 if(pfp->follow){
00300 pfp->xorg=pfp->x0;
00301 pfp->yorg=pfp->y0;
00302 }
00303
00304 hw->RestoreParameter();
00305
00306 return 0;
00307 }
00308
00309 long PeakFindScan::PFget0d(XSM_Hardware *hw, SPA_PeakFind_p *pfp ){
00310 long cnt;
00311 PARAMETER_SET hardpar;
00312 hardpar.N = DSP_E+1;
00313 hardpar.Cmd = DSP_CMD_GETCNT;
00314
00315 hardpar.hp[DSP_X0 ].value = (double)gapp->xsm->Inst->YA2Dig(pfp->xorg);
00316 hardpar.hp[DSP_Y0 ].value = (double)gapp->xsm->Inst->YA2Dig(pfp->yorg);
00317 hardpar.hp[DSP_ms ].value = 1e3*pfp->gate;
00318 hardpar.hp[DSP_E ].value = (double)gapp->xsm->Inst->eV2V(pfp->energy);
00319 hw->SetParameter(hardpar);
00320 hw->ReadData(&cnt, sizeof(long));
00321
00322 hw->RestoreParameter();
00323
00324 return cnt;
00325 }
00326
00327 int PeakFindScan::PFget2d(XSM_Hardware *hw, SPA_PeakFind_p *pfp ){
00328 PARAMETER_SET hardpar;
00329 pfp->ResizeBuffer();
00330
00331 hardpar.N = DSP_E+1;
00332 hardpar.Cmd = DSP_CMD_SCAN_PARAM;
00333
00334 hardpar.hp[DSP_X0 ].value = (double)gapp->xsm->Inst->YA2Dig(pfp->xorg);
00335 hardpar.hp[DSP_Y0 ].value = (double)gapp->xsm->Inst->YA2Dig(pfp->yorg);
00336 hardpar.hp[DSP_len ].value = (double)gapp->xsm->Inst->YA2Dig(pfp->radius*2.);
00337 hardpar.hp[DSP_N ].value = pfp->npkte;
00338 hardpar.hp[DSP_alpha].value = 0.;
00339 hardpar.hp[DSP_ms ].value = 1e3*pfp->gate2d;
00340 hardpar.hp[DSP_E ].value = (double)gapp->xsm->Inst->eV2V(pfp->energy);
00341 hw->SetParameter(hardpar);
00342
00343 hardpar.N = DSP_LXY+1;
00344 hardpar.Cmd = DSP_CMD_SCAN2D;
00345 hardpar.hp[DSP_X0 ].value = 0;
00346 hardpar.hp[DSP_Y0 ].value = 0;
00347 hardpar.hp[DSP_len ].value = 0;
00348 hardpar.hp[DSP_N ].value = 0;
00349 hardpar.hp[DSP_alpha].value = 0;
00350 hardpar.hp[DSP_ms ].value = 0;
00351 hardpar.hp[DSP_E ].value = 0;
00352 hardpar.hp[DSP_NX ].value = pfp->npkte2d;
00353 hardpar.hp[DSP_NY ].value = pfp->npkte2d;
00354 hardpar.hp[DSP_LXY ].value = (double)gapp->xsm->Inst->YA2Dig(pfp->radius*2.);
00355 hw->SetParameter(hardpar);
00356 hw->ReadData(pfp->buffer, pfp->buffersize*sizeof(long));
00357
00358 hw->RestoreParameter();
00359
00360 return 0;
00361 }
00362
00363
00364
00365
00366
00367
00368
00369 SPA_PeakFind_p::SPA_PeakFind_p(int idx, gchar *SetName)
00370 {
00371 index=idx;
00372 resName = g_strdup_printf("%s_%d", SetName, index);
00373
00374 XsmRescourceManager xrm(resName);
00375 xrm.Get("xOrg", &xorg, "0.0"); xnew=x0=xorg;
00376 xrm.Get("yOrg", &yorg, "0.0"); ynew=y0=yorg;
00377 xrm.Get("relLim", &rellim, "2.0");
00378 xrm.Get("absLim", &abslim, "10.0");
00379 xrm.Get("npkte", &npkte, "20");
00380 xrm.Get("npkte2d", &npkte2d, "40");
00381 xrm.Get("radius", &radius, "1.0");
00382 xrm.Get("gate", &gate, "20e-3");
00383 xrm.Get("gate2d", &gate2d, "5e-4");
00384 xrm.Get("Energy", &energy, "72.0");
00385 xrm.Get("Delta", &konvfac, "0.05");
00386
00387 XsmRescourceManager xrmPC("DSPPeakFindControl");
00388 xrmPC.Get("xSignum", &xsig, "1.0");
00389 xrmPC.Get("ySignum", &ysig, "1.0");
00390
00391 focview = NULL;
00392 buffer = NULL;
00393 buffersize=0;
00394
00395 xyscans = new Mem2d(npkte_alloc=npkte, 4, ZD_LONG);
00396 follow=FALSE;
00397 sleeptime=0.;
00398 maxloops = 1;
00399 enabled=TRUE;
00400 number=0; count=0; name=NULL;
00401 fitmode = PF_FITMODE_FIT2ND;
00402 yfwhm = xfwhm = fwhm = 1.;
00403 yI0 = xI0 = I0 = 1.;
00404 yxf0 = xxf0 = xf0 = 1.;
00405 offsetcorrection = 0.;
00406 }
00407
00408
00409 SPA_PeakFind_p::~SPA_PeakFind_p()
00410 {
00411
00412
00413 XsmRescourceManager xrm(resName);
00414 xrm.Put("xOrg", xorg);
00415 xrm.Put("yOrg", yorg);
00416 xrm.Put("relLim", rellim);
00417 xrm.Put("absLim", abslim);
00418 xrm.Put("npkte", npkte);
00419 xrm.Put("npkte2d", npkte2d);
00420 xrm.Put("radius", radius);
00421 xrm.Put("gate", gate);
00422 xrm.Put("gate2d", gate2d);
00423 xrm.Put("Energy", energy);
00424 xrm.Put("Delta", konvfac);
00425
00426 XsmRescourceManager xrmPC("DSPPeakFindControl");
00427 xrmPC.Put("xSignum", xsig);
00428 xrmPC.Put("ySignum", ysig);
00429
00430 if(focview){ delete focview; focview=NULL; }
00431 if(buffer){ g_free(buffer); buffer=NULL; }
00432
00433 g_free(resName);
00434 delete xyscans;
00435
00436 }
00437
00438
00439 int SPA_PeakFind_p::DoFit(){
00440 double dx, dy;
00441 if(FitFind(0, dx)) return -1;
00442 xfwhm = fwhm; skl(xfwhm);
00443 xI0 = I0;
00444 xxf0 = xf0; skltr(xxf0);
00445 dx = xxf0;
00446
00447 if(FitFind(1, dy)) return -1;
00448 yfwhm = fwhm; skl(yfwhm);
00449 yI0 = I0;
00450 yxf0 = xf0; skltr(yxf0);
00451 dy = yxf0;
00452
00453
00454
00455 shift = sqrt(dx*dx+dy*dy);
00456 if(shift > rellim){
00457 dx *= rellim/shift;
00458 dy *= rellim/shift;
00459 }
00460
00461 xnew = x0 + xsig*dx;
00462 ynew = y0 + ysig*dy;
00463
00464 if(xnew*xnew + ynew*ynew > abslim*abslim){
00465 xnew = x0;
00466 ynew = y0;
00467 return -1;
00468 }
00469
00470 return 0;
00471 }
00472
00473 int SPA_PeakFind_p::FitFind2nd(int xy, double &m){
00474 double a,b,c;
00475 int n = xyscans->GetNx();
00476 PI_DEBUG (DBG_L2, "SPA_PeakFind_p::FitFind2nd");
00477
00478 I0x = xyscans->GetDataPkt(n/2,0);
00479 I0y = xyscans->GetDataPkt(n/2,1);
00480
00481
00482
00483 StatInp fit(2, xyscans, xy);
00484
00485
00486 a = fit.GetPolyKoef(0);
00487 b = fit.GetPolyKoef(1);
00488 c = fit.GetPolyKoef(2);
00489
00490 fwhm = 0.;
00491 xf0 = -b/2./c;
00492 I0 = a+(b+c*xf0)*xf0;
00493
00494 xyscans->data->SetPtr(0,2+xy);
00495 for (int col = 0; col < n; col++) {
00496 xyscans->data->SetNext(fit.GetPoly((double)col));
00497
00498 }
00499
00500
00501 if(fabs(c) < 1e-7)
00502 return -1;
00503
00504 m = xf0 - .5;
00505 return 0;
00506 }
00507
00508 double tr_log(double x, double a){ return log(((x-a)<1.?1.:(x-a))); }
00509
00510 int SPA_PeakFind_p::FitFindGaus(int xy, double &m){
00511 int n = xyscans->GetNx();
00512 double a, b, c;
00513 double offset=0.;
00514
00515 PI_DEBUG (DBG_L2, "SPA_PeakFind_p::FitFindGaus");
00516
00517 I0x = xyscans->GetDataPkt(n/2,0);
00518 I0y = xyscans->GetDataPkt(n/2,1);
00519
00520 if(offsetcorrection > 0.1){
00521 double offsets[2];
00522 offsets[0] = xyscans->data->Z(0,xy);
00523 offsets[0] += xyscans->data->Z(1,xy);
00524 offsets[0] /= 2*offsetcorrection;
00525 offsets[1] = xyscans->data->Z(n-2,xy);
00526 offsets[1] += xyscans->data->Z(n-1,xy);
00527 offsets[1] /= 2*offsetcorrection;
00528 offset = offsets[0] > offsets[1] ? offsets[1] : offsets[0];
00529 }
00530
00531
00532
00533
00534 StatInp fit(2, xyscans, xy, tr_log, offset);
00535
00536
00537 a = fit.GetPolyKoef(0);
00538 b = fit.GetPolyKoef(1);
00539 c = fit.GetPolyKoef(2);
00540
00541 fwhm = 2.*sqrt(-0.6931472/c);
00542 xf0 = -b/2./c;
00543 I0 = exp(a-b*b/4./c);
00544
00545 xyscans->data->SetPtr(0,2+xy);
00546 for (int col = 0; col < n; col++) {
00547 xyscans->data->SetNext(offset+I0*exp(c*((double)col-xf0)*((double)col-xf0)));
00548 }
00549
00550 m = xf0;
00551 return 0;
00552 }
00553
00554 double tr_inv(double x, double a){ return 1./(((x-a)<1.?1.:(x-a))); }
00555
00556 int SPA_PeakFind_p::FitFindLorenz(int xy, double &m){
00557 int n = xyscans->GetNx();
00558 double a, b, c;
00559 double offset=0.;
00560
00561 PI_DEBUG (DBG_L2, "SPA_PeakFind_p::FitFindLorenz");
00562
00563 I0x = xyscans->GetDataPkt(n/2,0);
00564 I0y = xyscans->GetDataPkt(n/2,1);
00565
00566 if(offsetcorrection > 0.1){
00567 double offsets[2];
00568 offsets[0] = xyscans->data->Z(0,xy);
00569 offsets[0] += xyscans->data->Z(1,xy);
00570 offsets[0] /= 2.*offsetcorrection;
00571 offsets[1] = xyscans->data->Z(n-2,xy);
00572 offsets[1] += xyscans->data->Z(n-1,xy);
00573 offsets[1] /= 2.*offsetcorrection;
00574 offset = offsets[0] > offsets[1] ? offsets[1] : offsets[0];
00575 }
00576
00577
00578
00579
00580 StatInp fit(2, xyscans, xy, tr_inv, offset);
00581
00582
00583 a = fit.GetPolyKoef(0);
00584 b = fit.GetPolyKoef(1);
00585 c = fit.GetPolyKoef(2);
00586
00587 xf0 = -b/2./c;
00588 I0 = 4.*c/(4*a*c-b*b);
00589 fwhm = 2.*sqrt(1./c/I0);
00590
00591 xyscans->data->SetPtr(0,2+xy);
00592 for (int col = 0; col < n; col++) {
00593 xyscans->data->SetNext(offset+I0/(1.+c*I0*((double)col-xf0)*((double)col-xf0)));
00594 }
00595
00596 m = xf0;
00597 return 0;
00598 }
00599