Changeset 18625 for trunk/FACT++/drive


Ignore:
Timestamp:
09/18/16 14:50:59 (8 years ago)
Author:
tbretz
Message:
Removed reference to root dictionary, some minor update to disentengle from root and Mars as much as possible, changed path to horizon.dat
Location:
trunk/FACT++/drive
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/drive/TPointGui.cc

    r18618 r18625  
    11#include "TPointGui.h"
    22
     3#include <iomanip>
    34#include <fstream>
    45#include <stdlib.h>
     6
     7#include <TROOT.h>
     8#include <TClass.h>
     9#include <TSystem.h>
    510
    611#include <TGLabel.h>
     
    2429#include <TGraphErrors.h>
    2530
    26 #include "MLog.h"
    27 #include "MLogManip.h"
    28 
    29 #include "MGList.h"
    30 
    3131#include "TPointStar.h"
    3232
    33 ClassImp(TPointGui);
    34 
    3533using namespace std;
    3634
    37 TPointGui::TPointGui(const char *fname, const char *mod) : TGMainFrame(gClient->GetRoot(), 750, 435, kHorizontalFrame), fExitLoopOnClose(kFALSE),
    38    fAzMin(-180), fAzMax(180), fZdMin(0), fZdMax(90), fMagMin(0), fLimit(0.05)
     35TPointGui::TPointGui(const string fname, const string mod) : TGMainFrame(gClient->GetRoot(), 650, 435, kHorizontalFrame), fExitLoopOnClose(kFALSE),
     36   fAzMin(0), fAzMax(360), fZdMin(0), fZdMax(90), fMagMax(10), fLimit(0.05)
    3937{
    4038    fCoordinates.SetOwner();
    4139    fOriginal.SetOwner();
    4240
    43     fList = new MGList;
     41    fList = new TList;
    4442    fList->SetOwner();
     43
     44    gROOT->GetListOfCleanups()->Add(fList);
     45    fList->SetBit(kMustCleanup);
    4546
    4647    fFont = gVirtualX->LoadQueryFont("7x13bold");
     
    9091        AddCheckButton(vframe, fBending.GetVarName(i), i);
    9192
    92     TGButton *but = (TGButton*)fList->FindWidget(0);
     93    TGButton *but = (TGButton*)FindWidget(0);
    9394
    9495    comp->AddFrame(vframe, hints3);
     
    213214    TGTextEntry *entry1 = new TGTextEntry(v1, Form("%.1f", fAzMin),  kIdAzMin);
    214215    TGTextEntry *entry2 = new TGTextEntry(v2, Form("%.1f", fAzMax),  kIdAzMax);
    215     TGTextEntry *entry3 = new TGTextEntry(v3, Form("%.1f", fMagMin), kIdMagMin);
     216    TGTextEntry *entry3 = new TGTextEntry(v3, Form("%.1f", fMagMax), kIdMagMax);
    216217    TGTextEntry *entry4 = new TGTextEntry(v1, Form("%.1f", fZdMin),  kIdZdMin);
    217218    TGTextEntry *entry5 = new TGTextEntry(v2, Form("%.1f", fZdMax),  kIdZdMax);
     
    251252
    252253    // FIXME: Move this to the rc-file.
    253     ((TGCheckButton*)fList->FindWidget(0))->SetState(kButtonDown);
    254     ((TGCheckButton*)fList->FindWidget(1))->SetState(kButtonDown);
    255     ((TGCheckButton*)fList->FindWidget(5))->SetState(kButtonDown);
    256     ((TGCheckButton*)fList->FindWidget(6))->SetState(kButtonDown);
    257     ((TGCheckButton*)fList->FindWidget(9))->SetState(kButtonDown);
    258     ((TGCheckButton*)fList->FindWidget(11))->SetState(kButtonDown);
    259     ((TGCheckButton*)fList->FindWidget(15))->SetState(kButtonDown);
    260     ((TGCheckButton*)fList->FindWidget(16))->SetState(kButtonDown);
    261     ((TGCheckButton*)fList->FindWidget(17))->SetState(kButtonDown);
    262 
    263     ((TGCheckButton*)fList->FindWidget(19))->SetState(kButtonDisabled);
    264     ((TGCheckButton*)fList->FindWidget(20))->SetState(kButtonDisabled);
    265     ((TGCheckButton*)fList->FindWidget(21))->SetState(kButtonDisabled);
    266     ((TGCheckButton*)fList->FindWidget(22))->SetState(kButtonDisabled);
    267 
    268     ((TGCheckButton*)fList->FindWidget(19+2*MPointing::GetNumPar()))->SetState(kButtonDisabled);
    269     ((TGCheckButton*)fList->FindWidget(20+2*MPointing::GetNumPar()))->SetState(kButtonDisabled);
    270     ((TGCheckButton*)fList->FindWidget(21+2*MPointing::GetNumPar()))->SetState(kButtonDisabled);
    271     ((TGCheckButton*)fList->FindWidget(22+2*MPointing::GetNumPar()))->SetState(kButtonDisabled);
    272 
     254    ((TGCheckButton*)FindWidget(0))->SetState(kButtonDown);
     255    ((TGCheckButton*)FindWidget(1))->SetState(kButtonDown);
     256    ((TGCheckButton*)FindWidget(3))->SetState(kButtonDown);
     257    ((TGCheckButton*)FindWidget(4))->SetState(kButtonDown);
     258    ((TGCheckButton*)FindWidget(5))->SetState(kButtonDown);
     259    ((TGCheckButton*)FindWidget(6))->SetState(kButtonDown);
     260    ((TGCheckButton*)FindWidget(7))->SetState(kButtonDown);
     261    ((TGCheckButton*)FindWidget(8))->SetState(kButtonDown);
     262    ((TGCheckButton*)FindWidget(11))->SetState(kButtonDown);
     263    ((TGCheckButton*)FindWidget(12))->SetState(kButtonDown);
     264    ((TGCheckButton*)FindWidget(13))->SetState(kButtonDown);
     265    ((TGCheckButton*)FindWidget(14))->SetState(kButtonDown);
     266/*
     267    ((TGCheckButton*)FindWidget(19))->SetState(kButtonDisabled);
     268    ((TGCheckButton*)FindWidget(20))->SetState(kButtonDisabled);
     269    ((TGCheckButton*)FindWidget(21))->SetState(kButtonDisabled);
     270    ((TGCheckButton*)FindWidget(22))->SetState(kButtonDisabled);
     271
     272    ((TGCheckButton*)FindWidget(19+2*MPointing::GetNumPar()))->SetState(kButtonDisabled);
     273    ((TGCheckButton*)FindWidget(20+2*MPointing::GetNumPar()))->SetState(kButtonDisabled);
     274    ((TGCheckButton*)FindWidget(21+2*MPointing::GetNumPar()))->SetState(kButtonDisabled);
     275    ((TGCheckButton*)FindWidget(22+2*MPointing::GetNumPar()))->SetState(kButtonDisabled);
     276*/
    273277    SetWindowName("Telesto");
    274278    SetIconName("Telesto");
     
    279283    MapWindow();
    280284
    281     if (!TString(fname).IsNull())
    282         LoadStars(fname);
    283     if (!TString(mod).IsNull())
    284         fBending.Load(mod);
     285    if (!fname.empty())
     286        LoadStars(fname.c_str());
     287    if (!mod.empty())
     288        fBending.Load(mod.c_str());
    285289
    286290    DisplayBending();
     
    306310    bend.SetParameters(par); // Set Parameters [deg] to MPointing
    307311
     312    int cnt = 0;
    308313    for (int i=0; i<fCoordinates.GetSize(); i++)
    309314    {
     
    312317        if (set.GetStarZd()<fZdMin || set.GetStarZd()>fZdMax ||
    313318            set.GetStarAz()<fAzMin || set.GetStarAz()>fAzMax ||
    314             set.GetMag()   <fMagMin)
     319            set.GetMag()   >fMagMax)
    315320            continue;
    316321
    317322        set.Adjust(bend);
    318323
    319         Double_t err = 0.01; // [deg] = 0.25SE
     324        Double_t err = 0.0043; // [deg]
    320325        Double_t res = set.GetResidual();//(&err);
    321326        res /= err;
    322327
    323328        f += res*res;
    324     }
    325 
    326     f /= fCoordinates.GetSize();
     329        cnt++;
     330    }
     331
     332    f /= cnt;
    327333}
    328334
     
    351357void TPointGui::AddResetButton(TGCompositeFrame *f, Int_t id, TGLayoutHints *h, Int_t height)
    352358{
    353     TGPictureButton *but = new TGPictureButton(f, "tpoint/skull.xpm", id);
     359    TGPictureButton *but = new TGPictureButton(f, "drive/skull.xpm", id);
    354360    but->SetHeight(height); // Offsets from TGLayout
    355361    but->SetWidth(height);
     
    395401{
    396402    TGLabel *l1 = (TGLabel*)fLabel.At(3*MPointing::GetNumPar()+1);
    397     l1->SetText(Form("Before: %.1f +- %.1f SE", before, 0.));
     403    l1->SetText(Form("Before: %.1f arcsec", before*360*3600/16384));
    398404
    399405    TGLabel *l2 = (TGLabel*)fLabel.At(3*MPointing::GetNumPar()+2);
    400     l2->SetText(Form("After:  %.1f +- %.1f SE", after, 0.));
     406    l2->SetText(Form("After:  %.1f arcsec", after*360*3600/16384));
    401407
    402408    TGLabel *l3 = (TGLabel*)fLabel.At(3*MPointing::GetNumPar()+3);
    403     l3->SetText(Form("Backw:  %.1f +- %.1f SE", backw, 0.));
     409    l3->SetText(Form("Backw:  %.1f arcsec", backw*360*3600/16384));
    404410}
    405411
     
    410416    if (!view)
    411417    {
    412         gLog << err << "No View!" << endl;
     418        cout << "No View!" << endl;
    413419        return;
    414420    }
     
    434440    if (!view)
    435441    {
    436         gLog << err << "No View!" << endl;
     442        cout << "No View!" << endl;
    437443        return;
    438444    }
     
    548554    if (!view)
    549555    {
    550         gLog << err << "No View!" << endl;
     556        cout << "No View!" << endl;
    551557        return;
    552558    }
     
    555561    if (!fin)
    556562    {
    557         gLog << err << "ERROR - " << fname << " not found." << endl;
     563        cout << "ERROR - " << fname << " not found." << endl;
    558564        return;
    559565    }
     
    621627    if (!fin)
    622628    {
    623         gLog << err << "Collection '" << fname << "' not found!" << endl;
     629        cout << "Collection '" << fname << "' not found!" << endl;
    624630        return;
    625631    }
     
    637643        if (line.Length()==0)
    638644            continue;
    639 
     645/*
    640646        if (!line.EndsWith(".txt"))
    641647        {
    642             gLog << warn << "WARNING: " << line << endl;
     648            cout << "WARNING: " << line << endl;
    643649            continue;
    644650        }
    645 
     651*/
    646652        LoadStars(line);
    647653    }
     
    667673    if (!fin)
    668674    {
    669         gLog << err << "File '" << fname << "' not found!" << endl;
     675        cout << "File '" << fname << "' not found!" << endl;
    670676        return;
    671677    }
     
    685691    }
    686692
    687     gLog << all << "Found " << fOriginal.GetSize()-size;
    688     gLog << " sets of coordinates in " << fname;
    689     gLog << " (Total=" << fOriginal.GetSize() << ")" << endl;
     693    cout << "Found " << fOriginal.GetSize()-size;
     694    cout << " sets of coordinates in " << fname;
     695    cout << " (Total=" << fOriginal.GetSize() << ")" << endl;
    690696
    691697    fFileNameStars = fname;
     
    695701Float_t TPointGui::GetFloat(Int_t id) const
    696702{
    697     return atof(static_cast<TGTextEntry*>(fList->FindWidget(id))->GetText());
     703    return atof(static_cast<TGTextEntry*>(FindWidget(id))->GetText());
    698704}
    699705
     
    775781                fZdMax = GetFloat(kIdZdMax);
    776782                return kTRUE;
    777             case kIdMagMin:
    778                 fMagMin = GetFloat(kIdMagMin);
     783            case kIdMagMax:
     784                fMagMax = GetFloat(kIdMagMax);
    779785                return kTRUE;
    780786            case kIdLimit:
     
    795801    if (fOriginal.GetSize()==0)
    796802    {
    797         gLog << warn << "Sorry, no input data loaded..." << endl;
     803        cout << "Sorry, no input data loaded..." << endl;
    798804        return;
    799805    }
     
    803809        fCoordinates.Add(new TPointStar(*(TPointStar*)fOriginal.At(i)));
    804810
    805     gLog << all << "-----------------------------------------------------------------------" << endl;
     811    cout << "-----------------------------------------------------------------------" << endl;
    806812
    807813    gStyle->SetOptStat("emro");
     
    811817    TH1F hres3("Res3", " Residuals after backward correction ",  fOriginal.GetSize()/3, 0, 0.3);
    812818
    813     TProfile proaz ("ProAz",  " \\Delta profile vs. Az",  48, -180, 180);
    814     TProfile prozd ("ProZd",  " \\Delta profile vs. Zd",  60,    0, 90);
    815     TProfile promag("ProMag", " \\Delta profile vs. Mag", 40,    1,  4);
     819    TProfile proaz ("ProAz",  " \\Delta profile vs. Az",  24, 0, 360);
     820    TProfile prozd ("ProZd",  " \\Delta profile vs. Zd",  30, 0, 90);
     821    TProfile promag("ProMag", " \\Delta profile vs. Mag", 10, 1,  10);
    816822
    817823    hres1.SetXTitle("\\Delta [\\circ]");
     
    856862    for (int i=0; i<MPointing::GetNumPar(); i++)
    857863    {
    858         TGButton *l = (TGButton*)fList->FindWidget(i);
     864        TGButton *l = (TGButton*)FindWidget(i);
    859865        minuit.FixParameter(i);
    860866        if (l->GetState()==kButtonDown)
     
    865871    //minuit.Command("SHOW LIMITS");
    866872
    867     gLog << inf << endl;
    868     gLog << "Starting fit..." << endl;
    869     gLog << "For the fit an measurement error in the residual of ";
    870     gLog << "0.02deg (=1SE) is assumed." << endl;
    871     gLog << endl;
     873    cout << endl;
     874    cout << "Starting fit..." << endl;
     875    cout << "For the fit an measurement error in the residual of ";
     876    cout << "0.02deg (=1SE) is assumed." << endl;
     877    cout << endl;
    872878
    873879    Int_t ierflg = 0;
    874880    ierflg = minuit.Migrad();
    875     gLog << inf << "Migrad returns " << ierflg << endl;
     881    cout << "Migrad returns " << ierflg << endl;
    876882    // minuit.Release(2);
    877883    ierflg = minuit.Migrad();
    878     gLog << inf << "Migrad returns " << ierflg << endl << endl;
     884    cout << "Migrad returns " << ierflg << endl << endl;
    879885
    880886    //
     
    883889    fBending.GetMinuitParameters(minuit);
    884890    fBending.PrintMinuitParameters(minuit);
    885     gLog << endl;
     891    cout << endl;
    886892    //fBending.Save("bending_magic.txt");
    887893
     
    906912    b2.SetParameters(par);
    907913
    908     gLog << all << endl << "Sets with Residual exceeding " << fLimit << "deg:" << endl;
    909     gLog << "   StarAz  StarEl      RawAz   RawEl      Mag Residual  Filename" << endl;
     914    cout << endl << "Sets with Residual exceeding " << fLimit << "deg:" << endl;
     915    cout << "   StarAz  StarEl      RawAz   RawEl      Mag Residual  Filename" << endl;
    910916
    911917    //
     
    919925
    920926        ZdAz za(set0.GetStarZdAz());
    921         za *=kRad2Deg;
     927        za *= 180/M_PI;
    922928
    923929        //
     
    947953
    948954        if (resi>fLimit) // 0.13
    949             gLog << all << " " << orig << "  <" << Form("%5.3f", resi) << ">  " << orig.GetName() << endl;
     955            cout << " " << orig << "  <" << Form("%5.3f", resi) << ">  " << orig.GetName() << endl;
    950956
    951957        proaz.Fill(za.Az(), set0.GetResidual(&err));
     
    964970    }
    965971
    966     gLog << "done." << endl << endl;
     972    cout << "done." << endl << endl;
    967973
    968974    //
     
    971977    const Stat_t ov = hres2.GetBinContent(hres2.GetNbinsX()+1);
    972978    if (ov>0)
    973         gLog << warn << "WARNING: " << ov << " overflows in residuals." << endl;
    974 
    975 
    976 
    977     gLog << inf << dec << endl;
    978     gLog << "              Number of calls to FCN: " << minuit.fNfcn << endl;
    979     gLog << "Minimum value found for FCN (Chi^2?): " << minuit.fAmin << endl;
    980     gLog << "                  Fit-Probability(?): " << TMath::Prob(minuit.fAmin/*fOriginal.GetSize()*/, fOriginal.GetSize()-minuit.GetNumFreePars())*100 << "%" << endl;
    981     gLog << "                           Chi^2/NDF: " << minuit.fAmin/(fOriginal.GetSize()-minuit.GetNumFreePars()) << endl;
     979        cout << "WARNING: " << ov << " overflows in residuals." << endl;
     980
     981
     982
     983    cout << dec << endl;
     984    cout << "             Number of calls to FCN: " << minuit.fNfcn << endl;
     985    cout << "Minimum value found for FCN (Chi^2): " << minuit.fAmin << endl;
     986    cout << "                    Fit-Probability: " << TMath::Prob(minuit.fAmin/*fOriginal.GetSize()*/, fOriginal.GetSize()-minuit.GetNumFreePars())*100 << "%" << endl;
     987    cout << "                          Chi^2/NDF: " << minuit.fAmin/(fOriginal.GetSize()-minuit.GetNumFreePars()) << endl;
    982988    //cout << "Prob(?): " << TMath::Prob(fChisquare,ndf);
    983989
     
    989995    // bending correction itself
    990996    //
    991     gLog << endl;
    992     gLog << "Checking backward correction (raw-->star):" << endl;
     997    cout << endl;
     998    cout << "Checking backward correction (raw-->star):" << endl;
    993999    for (int i=0; i<fCoordinates.GetSize(); i++)
    9941000    {
     
    10081014            continue;
    10091015
    1010         gLog << "DBack: " << setw(6) << set0.GetStarZd() << " " << setw(7) << set0.GetStarAz() << ":  ";
    1011         gLog << "ResB="<< setw(7) << res0*60 << "  ResF=" << setw(7) << res1*60 << "  |ResB-ResF|=" << setw(7) << diff*60 << " arcmin" << endl;
    1012     }
    1013     gLog << "OK." << endl;
    1014     gLog << endl;
     1016        cout << "DBack: " << setw(6) << set0.GetStarZd() << " " << setw(7) << set0.GetStarAz() << ":  ";
     1017        cout << "ResB="<< setw(7) << res0*60 << "  ResF=" << setw(7) << res1*60 << "  |ResB-ResF|=" << setw(7) << diff*60 << " arcmin" << endl;
     1018    }
     1019    cout << "OK." << endl;
     1020    cout << endl;
    10151021
    10161022    const Double_t max1 = TMath::Max(gaz.GetHistogram()->GetMaximum(), gdaz.GetHistogram()->GetMaximum());
     
    10221028    const Double_t min3 = TMath::Min(grzd.GetHistogram()->GetMinimum(), graz.GetHistogram()->GetMinimum());
    10231029
    1024     const Double_t absmax1 = TMath::Max(max1, TMath::Abs(min1));
    1025     const Double_t absmax2 = TMath::Max(max2, TMath::Abs(min2));
    1026     const Double_t absmax3 = TMath::Max(max3, TMath::Abs(min3));
     1030    const Double_t absmax1 = 0.05;//TMath::Max(max1, TMath::Abs(min1));
     1031    const Double_t absmax2 = 0.05;//TMath::Max(max2, TMath::Abs(min2));
     1032    const Double_t absmax3 = 0.05;//TMath::Max(max3, TMath::Abs(min3));
    10271033
    10281034    gaz.SetMaximum(absmax1);
     
    12321238    cout << "-------------------------" << endl;
    12331239    cout << "before: " << Form("%6.4f", hres1.GetMean()) << " \xb1 " << Form("%6.4f", hres1.GetRMS()) << " deg \t";
    1234     cout << "before: " << Form("%4.1f", hres1.GetMean()*60) << " \xb1 " << Form("%.1f", hres1.GetRMS()*60) << " arcmin" << endl;
     1240    cout << "before: " << Form("%4.1f", hres1.GetMean()*3600) << " \xb1 " << Form("%.1f", hres1.GetRMS()*3600) << " arcsec" << endl;
    12351241    cout << "after:  " << Form("%6.4f", hres2.GetMean()) << " \xb1 " << Form("%6.4f", hres2.GetRMS()) << " deg \t";
    1236     cout << "after:  " << Form("%4.1f", hres2.GetMean()*60) << " \xb1 " << Form("%.1f", hres2.GetRMS()*60) << " arcmin" << endl;
     1242    cout << "after:  " << Form("%4.1f", hres2.GetMean()*3600) << " \xb1 " << Form("%.1f", hres2.GetRMS()*3600) << " arcsec" << endl;
    12371243    cout << "backw:  " << Form("%6.4f", hres3.GetMean()) << " \xb1 " << Form("%6.4f", hres3.GetRMS()) << " deg \t";
    1238     cout << "backw:  " << Form("%4.1f", hres3.GetMean()*60) << " \xb1 " << Form("%.1f", hres3.GetRMS()*60) << " arcmin" << endl;
     1244    cout << "backw:  " << Form("%4.1f", hres3.GetMean()*3600) << " \xb1 " << Form("%.1f", hres3.GetRMS()*3600) << " arcsec" << endl;
    12391245    cout << endl;
    12401246    cout << "before: " << Form("%4.1f", hres1.GetMean()*16348/360) << " \xb1 " << Form("%.1f", hres1.GetRMS()*16384/360) << " SE \t\t";
     
    13351341}
    13361342
     1343TObject *TPointGui::FindWidget(Int_t id) const
     1344{
     1345    if (id<0)
     1346        return NULL;
     1347
     1348    TObject *obj;
     1349    TIter Next(fList);
     1350    while ((obj=Next()))
     1351    {
     1352        const TGWidget *wid = (TGWidget*)obj->IsA()->DynamicCast(TGWidget::Class(), obj);
     1353        if (!wid)
     1354            continue;
     1355
     1356        if (id == wid->WidgetId())
     1357            return obj;
     1358    }
     1359    return NULL;
     1360}
  • trunk/FACT++/drive/TPointGui.h

    r18618 r18625  
    1212#include "MPointing.h"
    1313
    14 class MGList; // To be removed!!!
    1514class TPointStar;
    16 
     15class TVirtualPad;
    1716class TGLabel;
     17class TList;
    1818
    1919class TPointGui : public TGMainFrame
     
    3333        kIdZdMin,
    3434        kIdZdMax,
    35         kIdMagMin,
     35        kIdMagMax,
    3636        kIdLimit,
    3737    };
    3838
    39     MGList *fList;
     39    TList *fList;
    4040
    4141    TList fOriginal;
     
    5555    Float_t fZdMin;
    5656    Float_t fZdMax;
    57     Float_t fMagMin;
     57    Float_t fMagMax;
    5858
    5959    Float_t fLimit;
     
    6161    void Fcn(Int_t &/*npar*/, Double_t */*gin*/, Double_t &f, Double_t *par, Int_t /*iflag*/);
    6262    static void fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag);
     63
     64    TObject *FindWidget(Int_t id) const;
    6365
    6466    void AddTextButton(TGCompositeFrame *f, TString txt, Int_t id=-1, TGLayoutHints *h=0);
     
    7476    void DrawPolLine(TVirtualPad *pad, Double_t r0, Double_t phi0, Double_t r1, Double_t phi1);
    7577    void DrawSet(TVirtualPad *pad, TPointStar &set, Float_t scale=-1, Float_t angle=0);
    76     void DrawHorizon(TVirtualPad *pad, const char *fname="horizon.dat") const;
     78    void DrawHorizon(TVirtualPad *pad, const char *fname="drive/horizon.dat") const;
    7779
    7880    TString OpenDialog(TString &dir, EFileDialogMode mode=kFDOpen);
     
    8890
    8991public:
    90     TPointGui(const char *fname=NULL, const char *mod=NULL);
     92    TPointGui(const std::string fname, const std::string mod);
    9193    ~TPointGui();
    9294
    9395    void SetExitLoopOnClose(Bool_t b=kTRUE) { fExitLoopOnClose=b; }
    94 
    95     ClassDef(TPointGui, 0)
    9696};
    9797
Note: See TracChangeset for help on using the changeset viewer.