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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 #include <gtk/gtk.h>
00118 #include "config.h"
00119 #include "gxsm/plugin.h"
00120
00121
00122 static void PolarHist_init( void );
00123 static void PolarHist_about( void );
00124 static void PolarHist_configure( void );
00125 static void PolarHist_cleanup( void );
00126
00127
00128
00129 #define GXSM_TWO_SRC_PLUGIN__DEF
00130
00131
00132 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00133
00134 static gboolean PolarHist_run( Scan *Src, Scan *Dest );
00135 #else
00136
00137 static gboolean PolarHist_run( Scan *Src1, Scan *Src2, Scan *Dest );
00138 #endif
00139
00140
00141 GxsmPlugin PolarHist_pi = {
00142 NULL,
00143 NULL,
00144 0,
00145 NULL,
00146
00147
00148
00149
00150 "PolarHist-"
00151 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00152 "M1S"
00153 #else
00154 "M2S"
00155 #endif
00156 "-ST",
00157
00158
00159
00160
00161
00162 NULL,
00163
00164 "Calculates a Polar Histogramm from two Srcs: data, angle",
00165
00166 "Percy Zahl",
00167
00168 N_("_Math/_Statistics/"),
00169
00170 N_("Polar Histogramm"),
00171
00172 N_("from two Channels: 1.: data 2.:polar angle!"),
00173
00174 "no more info",
00175 NULL,
00176 NULL,
00177
00178
00179 PolarHist_init,
00180
00181
00182 NULL,
00183
00184
00185 PolarHist_about,
00186
00187
00188 PolarHist_configure,
00189
00190
00191 NULL,
00192
00193
00194 PolarHist_cleanup
00195 };
00196
00197
00198
00199
00200 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00201 GxsmMathOneSrcPlugin PolarHist_m1s_pi
00202 #else
00203 GxsmMathTwoSrcPlugin PolarHist_m2s_pi
00204 #endif
00205 = {
00206
00207 PolarHist_run
00208 };
00209
00210
00211 static const char *about_text = N_("Gxsm PolarHist Plugin\n\n"
00212 "This Plugin calculates a polar\n"
00213 "Histogramm of data in Src1,\n"
00214 "polar angle in Src2.");
00215
00216
00217
00218 GxsmPlugin *get_gxsm_plugin_info ( void ){
00219 PolarHist_pi.description = g_strdup_printf(N_("Gxsm MathOneArg PolarHist plugin %s"), VERSION);
00220 return &PolarHist_pi;
00221 }
00222
00223
00224
00225
00226 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00227 GxsmMathOneSrcPlugin *get_gxsm_math_one_src_plugin_info( void ) {
00228 return &PolarHist_m1s_pi;
00229 }
00230 #else
00231 GxsmMathTwoSrcPlugin *get_gxsm_math_two_src_plugin_info( void ) {
00232 return &PolarHist_m2s_pi;
00233 }
00234 #endif
00235
00236
00237
00238
00239
00240 int PolSlices = 180;
00241 int DataChannels = 200;
00242 double DataStart = 0.;
00243 double DataEnd = 90.;
00244 int Vmode = 2;
00245
00246
00247 static void PolarHist_init(void)
00248 {
00249 PI_DEBUG (DBG_L2, "PolarHist Plugin Init");
00250 }
00251
00252
00253 static void PolarHist_about(void)
00254 {
00255 const gchar *authors[] = { PolarHist_pi.authors, NULL};
00256 gtk_widget_show(gnome_about_new ( PolarHist_pi.name,
00257 VERSION,
00258 N_("(C) 2000 the Free Software Foundation"),
00259 about_text,
00260 authors,
00261 NULL, NULL, NULL
00262 ));
00263 }
00264
00265
00266 static void PolarHist_configure(void)
00267 {
00268 GtkWidget *dialog;
00269 GtkWidget *vbox;
00270 GtkWidget *hbox;
00271 GtkWidget *info;
00272 GtkWidget *input;
00273 Gtk_EntryControl *ec;
00274
00275 dialog = gnome_dialog_new(_("Polar Histogramm Setup"),
00276 GNOME_STOCK_BUTTON_OK,
00277 NULL);
00278
00279 gnome_dialog_set_close(GNOME_DIALOG(dialog), FALSE);
00280 gnome_dialog_close_hides(GNOME_DIALOG(dialog), FALSE);
00281 gnome_dialog_set_default(GNOME_DIALOG(dialog), 0);
00282
00283 vbox = gtk_vbox_new (FALSE, 0);
00284 gtk_widget_show (vbox);
00285
00286 gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox),
00287 vbox, TRUE, TRUE, GNOME_PAD);
00288
00289 info = gtk_label_new ("Polar Histogramm Setup");
00290 gtk_widget_show (info);
00291 gtk_box_pack_start(GTK_BOX(vbox), info, TRUE, TRUE, GNOME_PAD);
00292
00293 input = PolarHist_pi.app->mygtk_create_input("# angular slices", vbox, hbox);
00294 ec = new Gtk_EntryControl(PolarHist_pi.app->xsm->Unity,
00295 "Value out of range !",
00296 &PolSlices,
00297 2., 3600., ".0f", input);
00298
00299 input = PolarHist_pi.app->mygtk_create_input("# data channels", vbox, hbox);
00300 ec = new Gtk_EntryControl(PolarHist_pi.app->xsm->Unity,
00301 "Value out of range !",
00302 &DataChannels,
00303 2., 100000., ".0f", input);
00304
00305 info = gtk_label_new ("Data Range (0...0 -> auto)");
00306 gtk_widget_show (info);
00307 gtk_box_pack_start(GTK_BOX(vbox), info, TRUE, TRUE, GNOME_PAD);
00308
00309 input = PolarHist_pi.app->mygtk_create_input("Data Start", vbox, hbox);
00310 ec = new Gtk_EntryControl(PolarHist_pi.app->xsm->Unity,
00311 "Value out of range !",
00312 &DataStart,
00313 -1e10, 1e10, ".3f", input);
00314
00315 input = PolarHist_pi.app->mygtk_create_input("Data End", vbox, hbox);
00316 ec = new Gtk_EntryControl(PolarHist_pi.app->xsm->Unity,
00317 "Value out of range !",
00318 &DataEnd,
00319 -1e10, 1e10, ".3f", input);
00320
00321 input = PolarHist_pi.app->mygtk_create_input("Vmode 1=cir,2=rect", vbox, hbox);
00322 ec = new Gtk_EntryControl(PolarHist_pi.app->xsm->Unity,
00323 "Value out of range !",
00324 &Vmode,
00325 0., 10., ".0f", input);
00326
00327 gtk_widget_show(dialog);
00328
00329 gnome_dialog_run_and_close(GNOME_DIALOG(dialog));
00330 }
00331
00332
00333 static void PolarHist_cleanup(void)
00334 {
00335 PI_DEBUG (DBG_L2, "PolarHist Plugin Cleanup");
00336 }
00337
00338 double Phi(double dx, double dy){
00339 double q23=0.;
00340 if(dx<0.){
00341 q23=180.;
00342 if(dy<0. )
00343 q23=-180.;
00344 }
00345
00346 if(fabs(dx)>1e-6)
00347 return q23+180.*atan(dy/dx)/M_PI;
00348 else return dy>0.?90.:-90.;
00349 }
00350
00351
00352 #ifdef GXSM_ONE_SRC_PLUGIN__DEF
00353 static gboolean PolarHist_run(Scan *Src, Scan *Dest)
00354 #else
00355 static gboolean PolarHist_run(Scan *Src1, Scan *Src2, Scan *Dest)
00356 #endif
00357 {
00358
00359 if(Src1->data.s.nx != Src2->data.s.nx || Src1->data.s.ny != Src2->data.s.ny)
00360 return MATH_SELECTIONERR;
00361
00362 PolarHist_configure();
00363
00364
00365 #define GetNumValPhi(V,P) Num[PolSlices*(V) + (P)]
00366 #define IncNumValPhi(V,P) ++Num[PolSlices*(V) + (P)]
00367 long *Num = new long[PolSlices * DataChannels];
00368 memset(Num, 0, sizeof(Num));
00369
00370
00371 if((DataStart == 0. && DataEnd == 0.) | DataStart > DataEnd)
00372 Src1->mem2d->HiLo(&DataEnd, &DataStart, FALSE, NULL, NULL, 1);
00373
00374 double DataRange = DataEnd - DataStart;
00375 double SliceAng = 360./(double)PolSlices;
00376
00377
00378 for(int line=0; line<Src1->data.s.ny; line++)
00379 for(int col=0; col<Src1->data.s.nx; col++){
00380 int v = (int)rint((Src1->mem2d->GetDataPkt(col, line)-DataStart)*(double)DataChannels/DataRange);
00381 int p = (int)rint(Src2->mem2d->GetDataPkt(col, line)/SliceAng);
00382 p += PolSlices; p = p % PolSlices;
00383 if( v < 0 || v >= DataChannels || p < 0 || p >= PolSlices)
00384 continue;
00385 IncNumValPhi(v, p);
00386 }
00387
00388
00389
00390 UnitObj *u;
00391 Dest->data.SetXUnit(u=new UnitObj("rPhi","rPhi"));
00392 Dest->data.SetYUnit(u); delete u;
00393 Dest->data.SetZUnit(u=new UnitObj("#","#")); delete u;
00394 Dest->data.s.dz = 1.;
00395
00396 switch(Vmode){
00397 case 1:
00398 Dest->data.s.nx = Dest->data.s.ny = DataChannels*2-1;
00399 Dest->mem2d->Resize(Dest->data.s.nx, Dest->data.s.ny, ZD_FLOAT);
00400 Dest->data.s.rx = Dest->data.s.ry = DataRange;
00401 Dest->data.s.x0 = Dest->data.s.y0 = DataStart;
00402 Dest->mem2d->data->MkXLookup(-DataRange, DataRange);
00403 Dest->mem2d->data->MkYLookup(-DataRange, DataRange);
00404 for(int line=0; line<Dest->data.s.ny; line++)
00405 for(int col=0; col<Dest->data.s.nx; col++){
00406 int dx= col-Dest->data.s.nx/2;
00407 int dy=line-Dest->data.s.ny/2;
00408 int v = (int)rint(sqrt(dx*dx+dy*dy));
00409 int p = (int)rint(Phi(dx, dy)/SliceAng);
00410 p += PolSlices; p = p % PolSlices;
00411 if( v < 0 || v >= DataChannels || p < 0 || p >= PolSlices)
00412 continue;
00413 if(v > (int)((double)DataChannels/2/M_PI))
00414 Dest->mem2d->PutDataPkt((double)GetNumValPhi(v, p), col, line);
00415 else{
00416 double sumup=0.;
00417 if(v>0){
00418 for(int i=p-(int)((double)DataChannels/2/M_PI/v);
00419 i<=p+(int)((double)DataChannels/2/M_PI/v); ++i)
00420 sumup += GetNumValPhi(v, (i+PolSlices)%PolSlices);
00421 sumup /= (1+2*(int)((double)DataChannels/2/M_PI/v));
00422 sumup *= (double)DataChannels/2/M_PI/v;
00423 }
00424 else
00425 for(int i=0; i<PolSlices; ++i)
00426 sumup += GetNumValPhi(v, i);
00427 Dest->mem2d->PutDataPkt(sumup, col, line);
00428 }
00429 }
00430 break;
00431 default:
00432 Dest->data.s.nx = DataChannels;
00433 Dest->data.s.ny = PolSlices;
00434 Dest->mem2d->Resize(Dest->data.s.nx, Dest->data.s.ny, ZD_LONG);
00435 Dest->data.s.rx = Dest->data.s.ry = DataRange;
00436 Dest->data.s.x0 = Dest->data.s.y0 = DataStart;
00437 Dest->mem2d->data->MkXLookup(0., DataRange);
00438 Dest->mem2d->data->MkYLookup(0., 360.);
00439 for(int line=0; line<Dest->data.s.ny; line++)
00440 for(int col=0; col<Dest->data.s.nx; col++)
00441 Dest->mem2d->PutDataPkt((double)GetNumValPhi(col, line), col, line);
00442 break;
00443 }
00444
00445 delete[] Num;
00446
00447 return MATH_OK;
00448 }
00449
00450