Skip to content

Commit 301bb15

Browse files
committed
adding N Gaussian fit functionality
1 parent 5216b53 commit 301bb15

File tree

4 files changed

+621
-33
lines changed

4 files changed

+621
-33
lines changed

Diff for: .gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
rootscope_temp.C
2+
rootfiles/
3+
demo*.cxx
4+
log.txt

Diff for: myDialog.h

+288-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// Author : Pei-Luan Tai
33
// Contact: [email protected]
4-
// Last update: Dec 3, 2017
4+
// Last update: Aug 24, 2019
55
//***************************************/
66
#include <vector>
77
#include <TH1.h>
@@ -2483,11 +2483,275 @@ Dlg_double_gaussian::Dlg_double_gaussian( const TGWindow* p,
24832483
///////////////////////////////////////////////////////////////////////////////
24842484

24852485

2486+
2487+
2488+
// use this class to handle the initial condition.
2489+
class Dlg_N_gaussian: public TGMainFrame {
2490+
2491+
float* fPeaks_h;
2492+
float* fPeaks_center;
2493+
float* fPeaks_sigma;
2494+
float* fInitValue;
2495+
int fNpeaks;
2496+
2497+
2498+
Bool_t firstTime;
2499+
Int_t tabSwitch;
2500+
2501+
TGVerticalFrame* fVF;
2502+
TGLabel* fLabel_header[4];
2503+
2504+
TGLabel** fLabel_peaks;
2505+
TGNumberEntry** fEntry_peaks;
2506+
TString* fPeaksString;
2507+
2508+
TGHorizontalFrame* fHF_btns;
2509+
TGTextButton* fBtn_close;
2510+
TGTextButton* fBtn_cancel;
2511+
2512+
2513+
2514+
public:
2515+
2516+
// class constructor
2517+
Dlg_N_gaussian( const TGWindow* p,
2518+
float* peaks_h,
2519+
float* peaks_center,
2520+
float* peaks_sigma,
2521+
int npeaks );
2522+
2523+
void To_switch_tab();
2524+
2525+
void To_response_key( Event_t* );
2526+
2527+
// void To_focus_on_entry( Event_t* );
2528+
2529+
void Cancel();
2530+
2531+
void CloseWindow();
2532+
2533+
void Update_values();
2534+
2535+
};
2536+
2537+
2538+
void Dlg_N_gaussian::To_switch_tab(){
2539+
2540+
int itemN = 3 * fNpeaks;
2541+
2542+
if( tabSwitch == -1 ){ tabSwitch = itemN-1; }
2543+
if( tabSwitch % itemN ==0 && tabSwitch > 0 ) {
2544+
tabSwitch=0;
2545+
} // to reset.
2546+
2547+
// int peakIdx = tabSwitch / 3;
2548+
// int itemIdx = tabSwitch % fNpeaks;
2549+
2550+
fEntry_peaks[tabSwitch]->GetNumberEntry()->SetFocus();
2551+
fEntry_peaks[tabSwitch]->GetNumberEntry()->SelectAll();
2552+
}
2553+
2554+
2555+
2556+
void Dlg_N_gaussian::Update_values( ){
2557+
2558+
for( int i =0; i<fNpeaks; i++ ){
2559+
fPeaks_h[i] = fEntry_peaks[ 3*i+0 ]->GetNumber();
2560+
fPeaks_center[i] = fEntry_peaks[ 3*i+1 ]->GetNumber();
2561+
fPeaks_sigma[i] = fEntry_peaks[ 3*i+2 ]->GetNumber();
2562+
}
2563+
2564+
CloseWindow();
2565+
}
2566+
2567+
2568+
2569+
void Dlg_N_gaussian::Cancel(){
2570+
2571+
for( int i =0; i<fNpeaks; i++ ){
2572+
fPeaks_h[i] = 0.;
2573+
fPeaks_center[i] = 0.;
2574+
fPeaks_sigma[i] = 0.;
2575+
}
2576+
2577+
CloseWindow();
2578+
2579+
}
2580+
2581+
2582+
void Dlg_N_gaussian::CloseWindow(){
2583+
2584+
fBtn_close->SetState(kButtonDisabled); // to avoid double click.
2585+
fBtn_cancel->SetState(kButtonDisabled);
2586+
DeleteWindow();
2587+
2588+
}
2589+
2590+
2591+
// void Dlg_N_gaussian::To_focus_on_entry( Event_t* e) {
2592+
2593+
// seeming not working well.. it will frozen...
2594+
// if( firstTime ) {
2595+
// fEntry_peak1[0]->GetNumberEntry()->SelectAll();
2596+
// fEntry_peak1[0]->GetNumberEntry()->SetFocus();
2597+
//
2598+
// firstTime = false;
2599+
// }
2600+
// }
2601+
2602+
2603+
void Dlg_N_gaussian::To_response_key(Event_t* e) {
2604+
2605+
/* using space as the hotkey to finish the input. */
2606+
2607+
2608+
// for key symbol look up.
2609+
UInt_t key_symbol;
2610+
char tmp[2];
2611+
if ( e->fType == kGKeyPress )
2612+
{ gVirtualX->LookupString( e, tmp,sizeof(tmp), key_symbol ); }
2613+
2614+
if ( e->fType == kGKeyPress )
2615+
{
2616+
2617+
const unsigned key_enter = 36;
2618+
2619+
if( key_symbol == kKey_Tab ) { tabSwitch++; To_switch_tab(); }
2620+
2621+
else if( key_symbol == kKey_Backtab ) { tabSwitch--; To_switch_tab(); }
2622+
2623+
else if( e->fCode == key_enter ) { Update_values(); }
2624+
2625+
else if( key_symbol == kKey_Escape ) { CloseWindow(); }
2626+
}
2627+
}
2628+
2629+
2630+
2631+
2632+
// class constructor
2633+
Dlg_N_gaussian::Dlg_N_gaussian( const TGWindow* p,
2634+
float* peaks_h,
2635+
float* peaks_center,
2636+
float* peaks_sigma,
2637+
int npeaks )
2638+
: TGMainFrame(p, 10, 10)
2639+
{
2640+
2641+
firstTime = true;
2642+
tabSwitch = 0;
2643+
fPeaks_h = peaks_h;
2644+
fPeaks_center = peaks_center;
2645+
fPeaks_sigma = peaks_sigma;
2646+
fNpeaks = npeaks;
2647+
2648+
2649+
fInitValue = new float [ npeaks*3 ];
2650+
for( int i = 0; i<npeaks; i++ ){
2651+
fInitValue[3*i+0] = fPeaks_h[i];
2652+
fInitValue[3*i+1] = fPeaks_center[i];
2653+
fInitValue[3*i+2] = fPeaks_sigma[i];
2654+
2655+
}
2656+
2657+
2658+
SetCleanup(kDeepCleanup); // important step for closing windows properly.
2659+
2660+
TGLayoutHints* Layout1 = new TGLayoutHints( kLHintsCenterY, 2, 2, 2, 2);
2661+
2662+
2663+
//=========================================================
2664+
// using Matrix Layout.
2665+
2666+
fVF = new TGVerticalFrame( this, 200, 40);
2667+
2668+
Int_t nRow = npeaks + 1; // one for header
2669+
Int_t nCol = 4; // peakN, h, c, w.
2670+
fVF->SetLayoutManager ( new TGMatrixLayout( fVF , nRow, nCol) );
2671+
2672+
2673+
fLabel_header[0] = new TGLabel( fVF, "peakN " );
2674+
fLabel_header[1] = new TGLabel( fVF, " height " );
2675+
fLabel_header[2] = new TGLabel( fVF, " center " );
2676+
fLabel_header[3] = new TGLabel( fVF, " width " );
2677+
for( int i=0; i<4; i++ ){
2678+
fLabel_header[i]->SetTextJustify( kTextCenterX );
2679+
fVF->AddFrame( fLabel_header[i], Layout1 );
2680+
}
2681+
2682+
fLabel_peaks = new TGLabel* [npeaks] ;
2683+
fEntry_peaks = new TGNumberEntry* [ npeaks * 3];
2684+
2685+
for( int i=0; i<npeaks; i++ ){
2686+
2687+
fLabel_peaks[i] = new TGLabel( fVF, Form( "peak%d",i+1) );
2688+
fLabel_peaks[i]->SetTextJustify( kTextCenterX );
2689+
fVF->AddFrame( fLabel_peaks[i], Layout1 );
2690+
2691+
2692+
// number entries
2693+
for( int j=0; j<3; j++) {
2694+
2695+
int idx = j + 3 * i;
2696+
2697+
fEntry_peaks[idx]
2698+
= new TGNumberEntry( fVF, // base frame
2699+
fInitValue[idx], // inital value
2700+
12, // digit width
2701+
idx, // ID
2702+
TGNumberFormat::kNESRealOne);
2703+
2704+
fEntry_peaks[idx]->GetNumberEntry()
2705+
-> Connect( "ProcessedEvent(Event_t*)",
2706+
"Dlg_N_gaussian", this,
2707+
"To_response_key(Event_t*)");
2708+
2709+
fVF->AddFrame( fEntry_peaks[idx], Layout1 );
2710+
}
2711+
2712+
}
2713+
2714+
AddFrame( fVF, Layout1 );
24862715

24872716

24882717

24892718

24902719

2720+
TGLayoutHints* Layout2 = new TGLayoutHints( kLHintsExpandX, 2, 2, 2, 2);
2721+
fHF_btns = new TGHorizontalFrame( this , 200, 30);
2722+
2723+
//---------------------------------------------------------| Btn for close the window
2724+
2725+
fBtn_close = new TGTextButton( fHF_btns, "OK" );
2726+
fBtn_close -> Connect( "Clicked()", "Dlg_N_gaussian", this, "Update_values()" );
2727+
fHF_btns->AddFrame( fBtn_close, Layout2);
2728+
2729+
//---------------------------------------------------------| Btn for cancel the change
2730+
// all h,c,sigma are set to zero.
2731+
fBtn_cancel = new TGTextButton( fHF_btns, "Cancel" );
2732+
fBtn_cancel -> Connect( "Clicked()", "Dlg_N_gaussian", this, "Cancel()" );
2733+
fHF_btns->AddFrame( fBtn_cancel, Layout2);
2734+
2735+
AddFrame( fHF_btns, Layout2);
2736+
2737+
2738+
2739+
2740+
SetName("Dlg_N_gaussian");
2741+
SetWindowName("N Gaussian fit");
2742+
2743+
MapSubwindows();
2744+
Resize( GetDefaultSize() );
2745+
MapWindow();
2746+
2747+
gClient->WaitFor(this);
2748+
}
2749+
2750+
///////////////////////////////////////////////////////////////////////////////
2751+
2752+
2753+
2754+
24912755
class Dlg_to_find_peaks: public TGMainFrame {
24922756

24932757
Float_t* fSigma_guess;
@@ -2830,6 +3094,8 @@ class Dlg_Operation_histos: public TGMainFrame {
28303094
void to_display_histos( TString epr);
28313095

28323096
void to_apply_formula( TString epr);
3097+
3098+
void to_set_fitN( TString epr);
28333099
};
28343100

28353101

@@ -3557,6 +3823,25 @@ void Dlg_Operation_histos::to_display_histos( TString epr){
35573823

35583824
}
35593825

3826+
void Dlg_Operation_histos::to_set_fitN( TString epr ){
3827+
3828+
// when we input like "set fitN 3"
3829+
3830+
3831+
3832+
TObjArray* tmp_array = epr.Tokenize(" ");
3833+
Int_t substringN = tmp_array->GetEntries();
3834+
3835+
if( substringN < 3 ){
3836+
*fMessage = "set fitN: 2";
3837+
} else{
3838+
// to get the 3rd one.
3839+
TString s_tmp = ( (TObjString*)tmp_array->At(2) )->GetString();
3840+
*fMessage = "set fitN:" + s_tmp;
3841+
}
3842+
3843+
}
3844+
35603845
// this function parse the mathematical exprssion for the histogram
35613846
// operations. We will validate the input before apply the expression.
35623847
void Dlg_Operation_histos::Parse_expression( ){
@@ -3578,6 +3863,8 @@ void Dlg_Operation_histos::Parse_expression( ){
35783863

35793864
else if( epr.Contains("let") ) { to_apply_formula( epr ); }
35803865

3866+
else if( epr.Contains("set") && epr.Contains("fitN") ) { to_set_fitN( epr ); }
3867+
35813868
CloseWindow();
35823869

35833870
}

0 commit comments

Comments
 (0)