source: JEM-EUSO/esaf_lal/tags/v1_r0/esaf/packages/reconstruction/modules/shower/profile/src/ProfileModule.cc @ 117

Last change on this file since 117 was 117, checked in by moretto, 11 years ago

ESAF version compilable on mac OS

File size: 18.5 KB
Line 
1// $Id: ProfileModule.cc 2759 2006-09-07 08:10:49Z moreggia $
2// Author: Anne Stutz   Jun,  6 2005
3
4/*****************************************************************************
5 * ESAF: Euso Simulation and Analysis Framework                              *
6 *                                                                           *
7 *  Id: ProfileModule                                                           *
8 *  Package: <packagename>                                                   *
9 *  Coordinator: <coordinator>                                               *
10 *                                                                           *
11 *****************************************************************************/
12
13//_____________________________________________________________________________
14//
15// ProfileModule
16//
17// <extensive class description>
18//
19//   Config file parameters
20//   ======================
21//
22//   <parameter name>: <parameter description>
23//   -Valid options: <available options>
24//
25
26#include "ProfileModule.hh"
27#include "RecoEvent.hh"
28#include "RecoPhotonOnPupilData.hh"
29#include "RecoShowerTrackData.hh"
30#include "RecoShowerStepData.hh"
31#include <TMath.h>
32#include <TF1.h>
33#include <TStyle.h> //DELETE
34#include "EConst.hh"
35#include "KakimotoFluoCalculator.hh"
36#include "EsafSpectrum.hh"
37#include "O1_ClearSkyPropagator.hh"  //DELETE
38#include "TestGround.hh"
39#include "Atmosphere.hh"
40#include "RecoRootEvent.hh"
41#include "EarthVector.hh"
42#include "EsafRandom.hh"
43
44ClassImp(ProfileModule)
45
46using namespace sou;
47using namespace EConst;
48using namespace TMath;
49
50// parametrization definitions
51//_________________________________________________________________________________________
52Double_t Profile_GFA(Double_t* x, Double_t* par) {
53    //
54    // number of electrons at given depth according to Gaussian Function in Age parameterization.
55    // Formulae from C. Song, Astropart. Physics 22(2004)151
56    //
57    // par[0] : Nmax
58    // par[1] : Xmax
59    // par[2] : sigma
60    //
61   
62    Double_t Nmax  = par[0];
63    Double_t Xmax  = par[1];
64    Double_t sigma = par[2];
65    Double_t Age = 3*x[0] / (x[0] + 2*Xmax);
66
67    Double_t Ne = -1;
68   
69   
70    if(Age <= 0) return 0;
71   
72    Ne = Nmax * exp((-1./(2.*sigma*sigma)) * pow(Age - 1.,2));
73   
74    return Ne;
75}
76
77
78
79
80//_____________________________________________________________________________
81ProfileModule::ProfileModule() : RecoModule("Profile") {
82    //
83    // ctor
84    //
85
86}
87
88//_____________________________________________________________________________
89ProfileModule::~ProfileModule() {
90    //
91    // dtor
92    //
93}
94
95//_____________________________________________________________________________
96Bool_t ProfileModule::Init() {
97    //
98    // initializations
99    //
100
101    Msg(EsafMsg::Info) << "Initializing " << MsgDispatch;
102    string AnalysisType = Conf()->GetStr( "ProfileModule.fAnalysisType" );
103    fThetaMode = Conf()->GetStr( "ProfileModule.fThetaMode" );
104   
105    fSigmaZerror = Conf()->GetNum("ProfileModule.fSigmaZerror")*km;
106    fMeanZerror  = Conf()->GetNum("ProfileModule.fMeanZerror")*km;
107    fSigmaThetaerror = Conf()->GetNum("ProfileModule.fSigmaThetaerror")*DegToRad();
108    fMeanThetaerror  = Conf()->GetNum("ProfileModule.fMeanThetaerror")*DegToRad();
109   
110    if(AnalysisType == "Xmaxshift_airdensity") {
111        Msg(EsafMsg::Info) << "Analysis type for ProfileModule Xmaxshift_airdensity" << MsgDispatch;
112        fAnalysisType = Xmaxshift_airdensity;
113    }
114    else if(AnalysisType == "EShift_airDensity") {
115        Msg(EsafMsg::Info) << "Analysis type for ProfileModule EShift_AirDensity" << MsgDispatch;
116        fAnalysisType = EShift_airDensity;
117    }
118    else Msg(EsafMsg::Panic) << "Wrong config value ProfileModule.fAnalysisType " << fAnalysisType << " Setted to Xmaxshift_airdensity" << MsgDispatch;
119   
120    return kTRUE;
121}
122
123//_____________________________________________________________________________
124Bool_t ProfileModule::PreProcess() {
125    //
126    //
127    //
128   
129    fEvent          = NULL;
130    fTheta          = 0.;
131    fPhi            = 0.;
132    fXmax           = 0.;
133    fTrueXmax       = 0.;
134    fElecProfile_simu = 0;
135    fElecProfile_reco = 0;
136    ResetArrays();
137   
138    return kTRUE;
139}
140
141//_____________________________________________________________________________
142Bool_t ProfileModule::Process(RecoEvent *ev) {
143    //
144    //
145    //
146#ifdef DEBUG
147    Msg(EsafMsg::Debug)<<"Process"<< MsgDispatch;
148#endif
149
150    // manage the profile reconstruction chain
151    fEvent = ev; 
152   
153    // load information from previous modules
154    // amd buil
155    LoadModules();
156
157
158
159    // Assess the effect of air density profile on the shower dvpt (Xmax shift)
160    if(fAnalysisType == Xmaxshift_airdensity) {
161        XmaxShift_AirDensity();
162    }
163    else if(fAnalysisType == EShift_airDensity) {
164        EShift_AirDensity();
165    }
166   
167       
168           
169    return kTRUE;
170}
171
172//_____________________________________________________________________________
173void ProfileModule::LoadModules()  {
174    //
175    //
176    //
177#ifdef DEBUG
178          Msg(EsafMsg::Debug)<<"Load Modules"<< MsgDispatch;
179#endif
180   
181    fTheta =  fEvent->GetHeader().GetTrueTheta();
182    fPhi =  fEvent->GetHeader().GetTruePhi();
183   
184   
185    if(fAnalysisType == Xmaxshift_airdensity || fAnalysisType == EShift_airDensity) {
186        Msg(EsafMsg::Info)<<"************  ANALYSIS of Xmax / Energy shift due to air density profile  ************"<< MsgDispatch;
187       
188        // get input data
189        RecoShowerTrackData* trackdata = fEvent->GetRecoShowerTrackData();
190       
191        // get Xmax and showermaxpos truth
192        fTrueXmax = trackdata->GetXmax();
193        fTOAImpact = trackdata->GetTOAImpact();
194        fNbsteps_simu = trackdata->GetNumSteps();
195
196        // get true shower max 3D-POS
197        fShowerMaxPos = trackdata->GetShowerMaxPos();
198        fEarthImpact = trackdata->GetEarthImpact();
199    }
200   
201    else Msg(EsafMsg::Panic) << "Should not occur, analysis type :" <<fAnalysisType << MsgDispatch;
202}
203
204//_____________________________________________________________________________
205void ProfileModule::XmaxShift_AirDensity()  {
206    //
207    // Assess Xmax resolution : Simulated max position is used directly to reconstruct Xmax
208    //    - Max pos is modified     --> effect on Xmax
209    //    - atmosphere is modified  --> effect on Xmax
210    // NB : HERE THE PROFILE IS NOT ENTIRELY RECONSTRUCTED !! only the max position is used
211    //
212   
213    Msg(EsafMsg::Info)<<"XmaxShift_AirDensity analysis"<< MsgDispatch;
214   
215   
216   
217    // get atmosphere description (usually US-Std) and simulated depth of maximum
218    const Atmosphere* atmo = Atmosphere::Get();
219    EarthVector maxpos = fShowerMaxPos;
220    EarthVector TOAimpact = fTOAImpact;
221    fQuality = 0.;
222   
223   
224   
225    // introduce an error in Z determination, if Z underground or outside atmo, resp. 0km and TOA values are used
226    if(fSigmaZerror > 0. || fabs(fMeanZerror) > 0.) {
227        Double_t Zshift = IntroduceZerror();
228        Msg(EsafMsg::Info)<<"Zshift = "<<Zshift/km<<" km"<< MsgDispatch;
229        maxpos(2) += Zshift;
230        fZshift = Zshift;
231        if(maxpos.IsUnderSeaLevel()) {
232            maxpos = fShowerMaxPos;
233            maxpos(2) = sqrt( pow(EarthRadius(),2) - fShowerMaxPos.Perp2() ) - EarthRadius(); // <=> Zv=0
234            Msg(EsafMsg::Info)<<"Zshift PUT POS under sea level, NOW put at Zv = "<<maxpos.Zv()<< MsgDispatch;
235            fZshift =  1000.;
236            fQuality = -10.;
237        }
238        else if(maxpos.Zv() > atmo->GetTOAAltitude()) {
239            maxpos = fShowerMaxPos;
240            maxpos(2) = sqrt( pow(EarthRadius() + atmo->GetTOAAltitude(),2) - fShowerMaxPos.Perp2() ) - EarthRadius(); // <=> Zv=TOA
241            Msg(EsafMsg::Info)<<"Zshift PUT POS above TOA, NOW put at Zv = "<<maxpos.Zv()<< MsgDispatch;
242            fZshift =  1000.;
243            fQuality = 10.;
244        }
245    }
246   
247   
248   
249    // introduce an error in theta determination, TAKEN AT shower MAXIMUM, then TOA impact is calculated
250    if(fSigmaThetaerror > 0. || fabs(fMeanThetaerror) > 0.) {
251        Double_t ThetaShift = IntroduceThetaerror();
252        Msg(EsafMsg::Info)<<"Theta shift = "<<ThetaShift*RadToDeg()<<" deg"<< MsgDispatch;
253        fThetashift = ThetaShift;
254        EarthVector direction = (fTOAImpact - fShowerMaxPos).Unit();
255        direction.SetTheta(direction.Theta() + ThetaShift);
256        TOAimpact = atmo->ImpactAtTOA(fShowerMaxPos,direction);
257        fTOAImpact = TOAimpact;
258        if(fThetaMode == "earthimpact") {
259            if(fEarthImpact.Zv() > kAltitudeTolerance) fQuality = -100.;
260            else {
261                Double_t magmax = (fEarthImpact - fShowerMaxPos).Mag();
262                direction = (fTOAImpact - fEarthImpact).Unit();
263                direction.SetTheta(direction.Theta() + ThetaShift);
264                TOAimpact = atmo->ImpactAtTOA(fEarthImpact,direction);
265                fTOAImpact = TOAimpact;
266                maxpos = fEarthImpact + magmax*direction;
267                if( fabs((atmo->ImpactASL(maxpos,direction)).Z()) != HUGE) fQuality = -50.;
268            }
269        }
270    }
271   
272   
273   
274    // calculate Grammage between TOA and shower max position --> reco Xmax with current atmosphere config
275    fXmax = -10000.;
276    if(fQuality == 0.) fXmax = atmo->Grammage(maxpos,TOAimpact);
277}
278
279//_____________________________________________________________________________
280void ProfileModule::EShift_AirDensity()  {
281    //
282    // Assess Xmax resolution : Simulated max position is used directly to reconstruct Xmax
283    //    - Max pos is modified     --> effect on profile integral
284    //    - atmosphere is modified  --> effect on profile integral
285    //
286   
287    Msg(EsafMsg::Info)<<"EShift_AirDensity analysis"<< MsgDispatch;
288   
289   
290   
291    // init
292    const Atmosphere* atmo = Atmosphere::Get();
293    // get input data
294    RecoShowerTrackData* trackdata = fEvent->GetRecoShowerTrackData();
295    const RecoShowerStepData* recostep = 0;
296    // set arrays with new event data
297    ResetArrays(fNbsteps_simu);
298    for(Int_t i=0; i < fNbsteps_simu; i++) {
299        recostep = trackdata->GetStep(i);
300        fx_simu[i] = recostep->GetPosi().X();
301        fy_simu[i] = recostep->GetPosi().Y();
302        fz_simu[i] = recostep->GetPosi().Z();
303        fx_reco[i] = recostep->GetPosi().X();
304        fy_reco[i] = recostep->GetPosi().Y();
305        fz_reco[i] = recostep->GetPosi().Z();
306        fX_simu[i] = recostep->GetXi();
307        fX_reco[i] = recostep->GetXi();
308        fNe_simu[i] = recostep->GetNe();
309    }
310    fx_simu[fNbsteps_simu] = recostep->GetPosf().X();
311    fy_simu[fNbsteps_simu] = recostep->GetPosf().Y();
312    fz_simu[fNbsteps_simu] = recostep->GetPosf().Z();
313    fx_reco[fNbsteps_simu] = recostep->GetPosf().X();
314    fy_reco[fNbsteps_simu] = recostep->GetPosf().Y();
315    fz_reco[fNbsteps_simu] = recostep->GetPosf().Z();
316    fX_simu[fNbsteps_simu] = recostep->GetXf();
317    fX_reco[fNbsteps_simu] = recostep->GetXf();
318    fNbsteps_crash = fNbsteps_simu;
319   
320   
321   
322   
323    // introduce an error in Z determination
324    if(fSigmaZerror > 0. || fabs(fMeanZerror) > 0.) {
325        Bool_t stop_crash = kFALSE;
326        Double_t Zshift = IntroduceZerror();
327        Msg(EsafMsg::Info)<<"Zshift = "<<Zshift/km<<" km"<< MsgDispatch;
328        fZshift = Zshift;
329        fQuality = 0.;
330        for(Int_t i=0; i < fNbsteps_simu; i++) {
331            if(stop_crash) {
332                fNe_simu[i] = 0.;
333                continue;
334            }
335            EarthVector stepos(fx_reco[i],fy_reco[i],fz_reco[i]+Zshift);
336            if(stepos.IsUnderSeaLevel()) {
337                fNbsteps_crash = i-1;
338                if(fNbsteps_crash < 0) fNbsteps_crash = 0;
339                fQuality = -10.;
340                stop_crash = kTRUE;
341                fNe_simu[i] = 0.;
342                fNe_simu[i-1] = 0.;
343            }
344            else if(stepos.Zv() > atmo->GetTOAAltitude()) {
345                fQuality = 10.;
346                stop_crash = kTRUE;
347                fNe_simu[i] = 0.;
348                fNe_simu[i-1] = 0.;
349            }
350            else {
351                //apply Zshift
352                fz_reco[i] += Zshift;
353                // determine depth of the reco step
354                if(i == 0) {
355                    EarthVector TOAreco = fTOAImpact;
356                    TOAreco(2) += Zshift;
357                    fX_reco[i] = atmo->Grammage(stepos,TOAreco);
358                }
359                else {
360                    EarthVector prevpos(fx_reco[i-1],fy_reco[i-1],fz_reco[i-1]);
361                    fX_reco[i] = fX_reco[i-1] + atmo->Grammage(prevpos,stepos);
362                }
363            }
364        }
365        if(!stop_crash) {
366            // for last step
367            EarthVector stepos(fx_reco[fNbsteps_simu],fy_reco[fNbsteps_simu],fz_reco[fNbsteps_simu]+Zshift);
368            if(stepos.IsUnderSeaLevel()) {
369                fNbsteps_crash = fNbsteps_simu-1;
370                if(fNbsteps_crash < 0) fNbsteps_crash = 0;
371                fQuality = -10.;
372                stop_crash = kTRUE;
373                fNe_simu[fNbsteps_simu-1] = 0.;
374            }
375            else if(stepos.Zv() > atmo->GetTOAAltitude()) {
376                fQuality = 10.;
377                stop_crash = kTRUE;
378                fNe_simu[fNbsteps_simu-1] = 0.;
379            }
380            else {
381                // apply Zshift
382                fz_reco[fNbsteps_simu] += Zshift;
383                // determine depth of the reco step
384                EarthVector prevpos(fx_reco[fNbsteps_simu-1],fy_reco[fNbsteps_simu-1],fz_reco[fNbsteps_simu-1]);
385                fX_reco[fNbsteps_simu] = fX_reco[fNbsteps_simu-1] + atmo->Grammage(prevpos,stepos);
386            }
387        }
388    }
389   
390   
391
392
393   
394    // introduce an error in theta determination, TAKEN AT shower MAXIMUM
395    if(fSigmaThetaerror > 0. || fabs(fMeanThetaerror) > 0.) {
396        Bool_t stop_crash = kFALSE;
397        fQuality = 0.;
398        EarthVector REFpos = fShowerMaxPos;
399        if(fThetaMode == "earthimpact") {
400            REFpos = fEarthImpact;
401            if(fEarthImpact.Zv() > kAltitudeTolerance) {
402                stop_crash = kTRUE;
403                fQuality = -100.;
404            }
405        }
406        Double_t ThetaShift = IntroduceThetaerror();
407        Msg(EsafMsg::Info)<<"Theta shift = "<<ThetaShift*RadToDeg()<<" deg"<< MsgDispatch;
408        fThetashift = ThetaShift;
409        EarthVector pos_reco = REFpos;
410        EarthVector dir_up = (fTOAImpact - REFpos).Unit();
411        dir_up.SetTheta(dir_up.Theta() + ThetaShift);
412        EarthVector dir = -dir_up;
413        EarthVector pos1_simu(fx_simu[0],fy_simu[0],fz_simu[0]);
414        Double_t magmax = (pos1_simu - REFpos).Mag();
415        pos_reco += magmax*dir_up;
416        fx_reco[0] = pos_reco.X();
417        fy_reco[0] = pos_reco.Y();
418        fz_reco[0] = pos_reco.Z();
419        EarthVector TOAreco = atmo->ImpactAtTOA(REFpos,dir_up);
420        fX_reco[0] = atmo->Grammage(pos_reco,TOAreco);
421        for(Int_t i=1; i < fNbsteps_simu; i++) {
422            if(stop_crash) {
423                fNe_simu[i] = 0.;
424                continue;
425            }
426            EarthVector prevpos_simu(fx_simu[i-1],fy_simu[i-1],fz_simu[i-1]);
427            EarthVector nextpos_simu(fx_simu[i],fy_simu[i],fz_simu[i]);
428            pos_reco += (nextpos_simu - prevpos_simu).Mag() * dir;
429            if(pos_reco.IsUnderSeaLevel()) {
430                fNbsteps_crash = i-1;
431                if(fNbsteps_crash < 0) fNbsteps_crash = 0;
432                fQuality = -10.;
433                stop_crash = kTRUE;
434                fNe_simu[i] = 0.;
435                fNe_simu[i-1] = 0.;
436            }
437            else if(pos_reco.Zv() > atmo->GetTOAAltitude()) {
438                fQuality = 10.;
439                stop_crash = kTRUE;
440                fNe_simu[i] = 0.;
441                fNe_simu[i-1] = 0.;
442            }
443            else {
444                fx_reco[i] = pos_reco.X();
445                fy_reco[i] = pos_reco.Y();
446                fz_reco[i] = pos_reco.Z();
447                // determine depth of the reco step
448                EarthVector prevpos(fx_reco[i-1],fy_reco[i-1],fz_reco[i-1]);
449                fX_reco[i] = fX_reco[i-1] + atmo->Grammage(prevpos,pos_reco);
450            }
451        }
452        // for last step
453        if(!stop_crash) {
454            EarthVector prevpos_simu(fx_simu[fNbsteps_simu-1],fy_simu[fNbsteps_simu-1],fz_simu[fNbsteps_simu-1]);
455            EarthVector nextpos_simu(fx_simu[fNbsteps_simu],fy_simu[fNbsteps_simu],fz_simu[fNbsteps_simu]);
456            pos_reco += (nextpos_simu - prevpos_simu).Mag() * dir;
457            if(pos_reco.IsUnderSeaLevel()) {
458                fNbsteps_crash = fNbsteps_simu-1;
459                if(fNbsteps_crash < 0) fNbsteps_crash = 0;
460                fQuality = -10.;
461                stop_crash = kTRUE;
462                fNe_simu[fNbsteps_simu-1] = 0.;
463            }
464            else if(pos_reco.Zv() > atmo->GetTOAAltitude()) {
465                fQuality = 10.;
466                stop_crash = kTRUE;
467                fNe_simu[fNbsteps_simu-1] = 0.;
468            }
469            else {
470                fx_reco[fNbsteps_simu] = pos_reco.X();
471                fy_reco[fNbsteps_simu] = pos_reco.Y();
472                fz_reco[fNbsteps_simu] = pos_reco.Z();
473                // determine depth of the reco step
474                EarthVector prevpos(fx_reco[fNbsteps_simu-1],fy_reco[fNbsteps_simu-1],fz_reco[fNbsteps_simu-1]);
475                fX_reco[fNbsteps_simu] = fX_reco[fNbsteps_simu-1] + atmo->Grammage(prevpos,pos_reco);
476            }
477        }
478    }
479   
480   
481       
482   
483   
484    // build histos of simu and reco profile
485    fElecProfile_simu = new TH1F("profile_simu","profile_simu",fNbsteps_simu,fX_simu.GetArray());
486    fElecProfile_reco = new TH1F("profile_reco","profile_reco",fNbsteps_simu,fX_reco.GetArray());
487   
488    // set bin content to shower size Ne
489    for(Int_t i=0; i < fNbsteps_simu; i++) {
490        fElecProfile_reco->SetBinContent(i+1,fNe_simu[i]);
491        fElecProfile_simu->SetBinContent(i+1,fNe_simu[i]);
492    }
493   
494    // integrate profiles and store values in outputs
495    fRecoProfIntegral = fElecProfile_reco->Integral("width");
496    fSimuProfIntegral = fElecProfile_simu->Integral("width");
497}
498
499//_____________________________________________________________________________
500Double_t ProfileModule::IntroduceZerror() {
501    //
502    // introduce an error in Z-cordinate, then applied to XmaxShift_AirDensity() reco part
503    //
504    return EsafRandom::Get()->Gaus(fMeanZerror,fSigmaZerror);
505}
506
507//_____________________________________________________________________________
508Double_t ProfileModule::IntroduceThetaerror() {
509    //
510    // introduce an error in Theta, then applied to XmaxShift_AirDensity() reco part
511    //
512    return EsafRandom::Get()->Gaus(fMeanThetaerror,fSigmaThetaerror);
513}
514
515//_____________________________________________________________________________
516void ProfileModule::ResetArrays(Int_t n)  {
517    //
518    // clear TArrayD data, and define new size
519    //
520    fx_simu.Reset();
521    fy_simu.Reset();
522    fz_simu.Reset();
523    fx_reco.Reset();
524    fy_reco.Reset();
525    fz_reco.Reset();
526    fX_simu.Reset();
527    fX_reco.Reset();
528    fNe_simu.Reset();
529    fx_simu.Set(n+1);
530    fy_simu.Set(n+1);
531    fz_simu.Set(n+1);
532    fx_reco.Set(n+1);
533    fy_reco.Set(n+1);
534    fz_reco.Set(n+1);
535    fX_simu.Set(n+1);
536    fX_reco.Set(n+1);
537    fNe_simu.Set(n);
538    if(fElecProfile_simu) SafeDelete(fElecProfile_simu);
539    if(fElecProfile_reco) SafeDelete(fElecProfile_reco);
540}
541
542//_____________________________________________________________________________
543Bool_t ProfileModule::PostProcess() {
544    //
545    //
546    //
547    ResetArrays();
548   
549    return kTRUE;
550}
551
552//_____________________________________________________________________________
553Bool_t ProfileModule::Done() {
554    //
555    //chi
556    //
557
558    Msg(EsafMsg::Info)<<"ProfileModule done. "<< MsgDispatch;
559    return kTRUE;
560}
561
562//_____________________________________________________________________________
563void ProfileModule::UserMemoryClean()  {
564    //
565    // delete user objects
566    //
567   
568    ResetArrays();
569}
570
571//_____________________________________________________________________________
572Bool_t ProfileModule::SaveRootData(RecoRootEvent *fRecoRootEvent) {
573    //
574    //
575    //
576#ifdef DEBUG
577    Msg(EsafMsg::Debug)<<"Save reco root data"<< MsgDispatch;
578#endif
579   
580    RecoProfile& output = fRecoRootEvent->GetRecoProfile();
581   
582    // profile outputs
583    output.SetQuality(fQuality);
584    output.SetXmax(fXmax*cm2/g);
585    output.SetTrueXmax(fTrueXmax*cm2/g);
586    output.SetRecoProfIntegral(fRecoProfIntegral*cm2/g);
587    output.SetSimuProfIntegral(fSimuProfIntegral*cm2/g);
588    output.SetZshift(fZshift/km);
589    output.SetThetashift(fThetashift*RadToDeg());
590    output.SetTOAImpact(fTOAImpact.X(),fTOAImpact.Y(),fTOAImpact.Z());
591
592    return kTRUE;
593}
594
595
596
Note: See TracBrowser for help on using the repository browser.