コード例 #1
0
TGraph GetCurve(int Points,const double & hi_ex_set)
{
  TGraph curve;
  if(!gPrimaryReaction.IsSet()){
    std::cout<<"Reaction Masses have not been set"<<std::endl;
    exit(EXIT_FAILURE);
  }
  if(!gPrimaryReaction.BeamEnergy()){
    std::cout<<"Beam Energy has not been set"<<std::endl;
    exit(EXIT_FAILURE);
  }

  sim::RN_SimEvent evt1(gPrimaryReaction.BeamEnergy(),gPrimaryReaction.M_Beam(),gPrimaryReaction.M_Target(),gPrimaryReaction.M_Recoil(),gPrimaryReaction.M_Fragment()); 
  // Fill the points of the kinematic curve
  int p=0;
  while(p<Points){
    double theta_deg = 180.0*p/Points;
    double phi=2.*M_PI*global::myRnd.Rndm();

    TVector3 nv; nv.SetMagThetaPhi(1.,theta_deg*M_PI/180.0,phi);
    if(!evt1.radiate_in_CM(nv,hi_ex_set))
      continue;
    else 
      curve.SetPoint(p, evt1.getLVrad().Theta()*180/3.14,(double)(evt1.getLVrad().E()-evt1.getLVrad().M()));      
    p++;
  }
  // end for(p)    

  return curve;
}
コード例 #2
0
ファイル: noAveBounceStdy.C プロジェクト: jetatar/snowShovel
Double_t getShiftChi2(const Double_t* thetaPhi) {
   Double_t chi2(0), c(0);

   TVector3 norm; norm.SetMagThetaPhi(1.0, thetaPhi[0], thetaPhi[1]);
   for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
      for (Int_t xc=0; xc<ch; ++xc) {
         Double_t dtcor=0;
         for (Int_t i=(ch-xc); i>0; --i) {
            dtcor += dtCorrs[ch-i];
         }
         const TVector3& posCh = getStnPos(ch);
         const TVector3& posXc = getStnPos(xc);
         const Double_t  disCh = -(posCh.Dot(norm));
         const Double_t  disXc = -(posXc.Dot(norm));
         // !!! check sign of delta(distance) and dtcor!
         const Double_t  dt = kSmpRate * (             // from ns to samples
            ( (disCh-disXc) * kNgTopFern / kC_m_ns )   // from m to ns
            + dtcor );                                 // correct dt offset (ns)
         // FIXME: dt in samples, maxdt in ns
         if (TMath::Abs(dt)>maxdt) {
            // really don't like being out of bounds
            c = TMath::Exp(dt*dt);
            if (c>kReallyBig) {
               c = kReallyBig;
            }
         } else {
            // get the correlation coefficient for this dt (in num samples)
            c = gspc[ch][xc]->Eval(dt) - 1.0;
         }
         chi2 += c*c;
      }
   }
   return chi2;
}
コード例 #3
0
ファイル: noAveBounceStdy.C プロジェクト: jetatar/snowShovel
Double_t getShiftLL(const Double_t* thetaPhi) {
   
   Double_t chi2(1), c(0), oo(0);

   TVector3 norm; norm.SetMagThetaPhi(1.0, thetaPhi[0], thetaPhi[1]);
   for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
      for (Int_t xc=0; xc<ch; ++xc) {
         Double_t dtcor=0;
         for (Int_t i=(ch-xc); i>0; --i) {
            dtcor += dtCorrs[ch-i];
         }
         const TVector3& posCh = getStnPos(ch);
         const TVector3& posXc = getStnPos(xc);
         const Double_t  disCh = -(posCh.Dot(norm));
         const Double_t  disXc = -(posXc.Dot(norm));
         // !!! check sign of delta(distance) and dtcor!
         Double_t  dt = 
            ( (disCh-disXc) * kNgTopFern / kC_m_ns ) // from m to ns
            + dtcor;                                 // correct dt offset (ns)
         const Double_t odt = dt;
         Bool_t oob=kFALSE;
         if (dt<-maxdt) {
            dt  = -maxdt;
            oob = kTRUE;
         } else if (dt>maxdt) {
            dt  = maxdt;
            oob = kTRUE;
         }
         dt *= kSmpRate;
         c = getProbFromCorrCoef(gspl[ch][xc]->Eval(dt));
         if (oob) {
            const Double_t wa = TMath::Abs(odt) - maxdt;
            oo += wa*wa;
         }
         /*
         if (TMath::Abs(dt)>maxdt) {
            // really don't like being out of bounds
            c = TMath::Exp(-dt*dt);
         } else {
            // get the correlation coefficient for this dt (in num samples)
            const Double_t  corco = gspl[ch][xc]->Eval(dt);
            c = getProbFromCorrCoef(corco);
         }
         if (c>1.0) {
            Fatal("getShiftLL","Got ll term > 1 (%g)",c);
         }
         */
         chi2 *= c;
      }
   }
   chi2 = -TMath::Log(chi2);
   chi2 += oo;
   return chi2;
}
コード例 #4
0
TGraph GetSecondaryDecayCurve(int Points,const double & hi_ex_set,const double& decay_ex_set)
{
  TGraph curve;
  if(!gPrimaryReaction.IsSet()){
    std::cout<<"Reaction Masses have not been set"<<std::endl;
    exit(EXIT_FAILURE);
  }
  if(!gPrimaryReaction.BeamEnergy()){
    std::cout<<"Beam Energy has not been set"<<std::endl;
    exit(EXIT_FAILURE);
  }
 
  sim::RN_SimEvent evt1(gPrimaryReaction.BeamEnergy(),gPrimaryReaction.M_Beam(),gPrimaryReaction.M_Target(),gPrimaryReaction.M_Recoil(),gPrimaryReaction.M_Fragment());
  sim::RN_SimEvent evt2(gPrimaryReaction.M_Fragment(),gPrimaryReaction.M_Decay_Product(),gPrimaryReaction.M_Heavy_Decay());
  // Fill the points of the kinematic curve
  int p=0;
  while(p<Points){
    double theta_deg = 175; // assume backward angle from inverse kinematics
    double phi=2.*M_PI*global::myRnd.Rndm();
    
    TVector3 nv; nv.SetMagThetaPhi(1.,theta_deg*M_PI/180.0,phi);
    if(!evt1.radiate_in_CM(nv,hi_ex_set))
      continue;

    theta_deg = 180* p / Points;
    phi = 2.*M_PI*global::myRnd.Rndm();
    TVector3 pv; pv.SetMagThetaPhi(1.,theta_deg*M_PI/180.0,phi);
    if(!evt2.radiate_in_CM(evt1.getLVhi(),pv,decay_ex_set))
      continue;

    curve.SetPoint(p, evt2.getLVrad().Theta()*180/3.14,(double)(evt2.getLVrad().E() - evt2.getLVrad().M()));
    p++;
  }
  // end for(p)    

  return curve;
}
コード例 #5
0
Double_t getAngleChi2(const Double_t* thetaPhi) {
   Double_t chi2(0), c(0);
   
   TVector3 norm; norm.SetMagThetaPhi(1.0, thetaPhi[0], thetaPhi[1]);
   for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
      for (Int_t xc=0; xc<ch; ++xc) {
         const TVector3& posCh = getStnPos(ch);
         const TVector3& posXc = getStnPos(xc);
         const Double_t  disCh = -(posCh.Dot(norm));
         const Double_t  disXc = -(posXc.Dot(norm));
         // !!! check sign of delta(distance) and dtcor!
         const Double_t  dt = (disCh-disXc) * kNgTopFern / kC_m_ns;  // from m to ns
         const Double_t bdt = thetaPhi[2+ch] - thetaPhi[2+xc];

         c = (dt-bdt);
         chi2 += c*c;
         /*
         Printf("(%g,%g) d[%d]=%g, d[%d]=%g, bdt=%g, sch=%g, sxc=%g, dt=%g, c=%g",
                thetaPhi[0]*TMath::RadToDeg(), thetaPhi[1]*TMath::RadToDeg(),
                ch, thetaPhi[2+ch], xc, thetaPhi[2+xc], bdt, disCh, disXc, dt, c);
         */
      }
   }
   
#ifdef DEBUG_ANGLE
   if (dbgth!=0) {
      dbgth->SetPoint(dbgth->GetN(), thetaPhi[0]*TMath::RadToDeg(),
                      chi2);
      dbgphi->SetPoint(dbgphi->GetN(), thetaPhi[1]*TMath::RadToDeg(),
                      chi2);
   }
#endif
   
   return chi2;
   
}
コード例 #6
0
void fill(int const kf, TLorentzVector* b, double weight, TLorentzVector const& p1Mom, TLorentzVector const& p2Mom, TVector3 v00)
{
   int const centrality = floor(nCent * gRandom->Rndm());

   TVector3 const vertex = getVertex(centrality);
   // smear primary vertex
   // float const sigmaVertex = sigmaVertexCent[cent];
   // TVector3 const vertex(gRandom->Gaus(0, sigmaVertex), gRandom->Gaus(0, sigmaVertex), gRandom->Gaus(0, sigmaVertex));

   v00 += vertex;

   // smear momentum
   TLorentzVector const p1RMom = smearMom(0, p1Mom);
   TLorentzVector const p2RMom = smearMom(0, p2Mom);

   // smear position
   TVector3 const p1RPos = smearPosData(0, vertex.z(), centrality, p1RMom, v00);
   TVector3 const p2RPos = smearPosData(0, vertex.z(), centrality, p2RMom, v00);
   // TVector3 const kRPos = smearPos(kMom, kRMom, v00);
   // TVector3 const pRPos = smearPos(pMom, pRMom, v00);

   // reconstruct
   TLorentzVector const rMom = p1RMom + p2RMom;
   float const p1Dca = dca(p1Mom.Vect(), v00, vertex);
   float const p2Dca = dca(p2Mom.Vect(), v00, vertex);
   float const p1RDca = dca(p1RMom.Vect(), p1RPos, vertex);
   float const p2RDca = dca(p2RMom.Vect(), p2RPos, vertex);

   TVector3 v0;
   float const dca12 = dca1To2(p1RMom.Vect(), p1RPos, p2RMom.Vect(), p2RPos, v0);
   float const decayLength = (v0 - vertex).Mag();
   float const dcaD0ToPv = dca(rMom.Vect(), v0, vertex);
   float const cosTheta = (v0 - vertex).Unit().Dot(rMom.Vect().Unit());
   float const angle12 = p1RMom.Vect().Angle(p2RMom.Vect());

   TLorentzVector p1RMomRest = p1RMom;
   TVector3 beta;
   beta.SetMagThetaPhi(rMom.Beta(), rMom.Theta(), rMom.Phi());
   p1RMomRest.Boost(-beta);
   float const cosThetaStar = rMom.Vect().Unit().Dot(p1RMomRest.Vect().Unit());

   // save
   float arr[100];
   int iArr = 0;
   arr[iArr++] = centrality;
   arr[iArr++] = vertex.X();
   arr[iArr++] = vertex.Y();
   arr[iArr++] = vertex.Z();

   arr[iArr++] = kf;
   arr[iArr++] = b->M();
   arr[iArr++] = b->Perp();
   arr[iArr++] = b->PseudoRapidity();
   arr[iArr++] = b->Rapidity();
   arr[iArr++] = b->Phi();
   arr[iArr++] = v00.X();
   arr[iArr++] = v00.Y();
   arr[iArr++] = v00.Z();

   arr[iArr++] = rMom.M();
   arr[iArr++] = rMom.Perp();
   arr[iArr++] = rMom.PseudoRapidity();
   arr[iArr++] = rMom.Rapidity();
   arr[iArr++] = rMom.Phi();
   arr[iArr++] = v0.X();
   arr[iArr++] = v0.Y();
   arr[iArr++] = v0.Z();

   arr[iArr++] = dca12;
   arr[iArr++] = decayLength;
   arr[iArr++] = dcaD0ToPv;
   arr[iArr++] = cosTheta;
   arr[iArr++] = angle12;
   arr[iArr++] = cosThetaStar;

   arr[iArr++] = p1Mom.M();
   arr[iArr++] = p1Mom.Perp();
   arr[iArr++] = p1Mom.PseudoRapidity();
   arr[iArr++] = p1Mom.Rapidity();
   arr[iArr++] = p1Mom.Phi();
   arr[iArr++] = p1Dca;

   arr[iArr++] = p1RMom.M();
   arr[iArr++] = p1RMom.Perp();
   arr[iArr++] = p1RMom.PseudoRapidity();
   arr[iArr++] = p1RMom.Rapidity();
   arr[iArr++] = p1RMom.Phi();
   arr[iArr++] = p1RPos.X();
   arr[iArr++] = p1RPos.Y();
   arr[iArr++] = p1RPos.Z();
   arr[iArr++] = p1RDca;
   arr[iArr++] = tpcReconstructed(0,1,centrality,p1RMom);

   arr[iArr++] = p2Mom.M();
   arr[iArr++] = p2Mom.Perp();
   arr[iArr++] = p2Mom.PseudoRapidity();
   arr[iArr++] = p2Mom.Rapidity();
   arr[iArr++] = p2Mom.Phi();
   arr[iArr++] = p2Dca;

   arr[iArr++] = p2RMom.M();
   arr[iArr++] = p2RMom.Perp();
   arr[iArr++] = p2RMom.PseudoRapidity();
   arr[iArr++] = p2RMom.Rapidity();
   arr[iArr++] = p2RMom.Phi();
   arr[iArr++] = p2RPos.X();
   arr[iArr++] = p2RPos.Y();
   arr[iArr++] = p2RPos.Z();
   arr[iArr++] = p2RDca;
   arr[iArr++] = tpcReconstructed(0,-1,centrality,p2RMom);

   arr[iArr++] = matchHft(1, vertex.z(), centrality, p1RMom);
   arr[iArr++] = matchHft(0, vertex.z(), centrality, p2RMom);

   nt->Fill(arr);
}
コード例 #7
0
ファイル: buildFakeAngTree.C プロジェクト: jetatar/snowShovel
void buildFakeAngTree(const Char_t* outtag,
                      const Float_t timereso,     // ns
                      const UInt_t  simevts=1,
                      const Float_t thetaOpt=400, // deg
                      const Float_t phiOpt=400,   // deg
                      const Float_t coneOpt=400,  // deg
                      const UInt_t  rseed=23192,
                      const Float_t norm=100.0,   // mV
                      const Float_t noise=20.0,   // mV
                      const Char_t* outdir="/data/users/cjreed/work/simEvts",
                      const Char_t* infn="/w2/arianna/jtatar/nt.sigtemps.root",
                      const Char_t* geofn="/data/users/cjreed/work/"
                                          "BounceStudy/Stn10/"
                                          "CampSiteGeometry.root") {
   // if any of the angles (thetaOpt, phiOpt, coneOpt) > 360, a random
   // value will be used instead
   //
   // expect angles in the Templates tree to be in degrees
   //
   // expect the waveforms in the Templates tree to have amplitude 1
   
   TRandom3 rnd(rseed);
   
   
   geof = TFile::Open(geofn);
   gg = dynamic_cast<TGeoManager*>(geof->Get("CampSite2013"));
   site = dynamic_cast<const TSnGeoStnSite*>(gg->GetTopVolume());
   
   
   TVector3 pos[NSnConstants::kNchans], nvec[NSnConstants::kNchans];
   for (UChar_t ch=0; ch<NSnConstants::kNchans; ++ch) {
      site->SetLPDAPosition(ch, pos[ch]);
      site->SetLPDANormalVec(ch, nvec[ch]);
      Printf("pos ch%d:",ch);
      pos[ch].Print();
      Printf("normal ch%d:",ch);
      nvec[ch].Print();
   }
   
   TArrayD zeros(6);
   
   
   inf = TFile::Open(infn);
   nnt = dynamic_cast<TTree*>(inf->Get("Templates"));
   
   TString infns(infn);
   TString indir;
   Int_t fl(0);
   if (infns.Contains('/')) {
      fl = infns.Last('/') + 1;
      indir = infns(0, fl-1);
   }
   TString plaininfn = infns(fl, infns.Length()-fl);
   TString outfn = Form("%s/FakeEvts.%s.%s", outdir, outtag,
                        plaininfn.Data());
   outf = TFile::Open(outfn.Data(),"recreate");
   outf->cd();
   TParameter<Float_t> trp("TimeResolution", timereso);
   trp.Write();
   TParameter<Float_t> nmp("Normalization", norm);
   nmp.Write();
   TParameter<Float_t> nop("NoiseRMS", noise);
   nop.Write();
   TParameter<UInt_t> rsp("RandomSeed", rseed);
   rsp.Write();
   
   
   TSnCalWvData* wave = new TSnCalWvData;
   Float_t eang(0), hang(0), hpf(0), limiter(0), coneang(0);
   Bool_t bice(kFALSE);
   nnt->SetBranchAddress("wave.",&wave);
   nnt->SetBranchAddress("EAng",&eang);
   nnt->SetBranchAddress("HAng",&hang);
   nnt->SetBranchAddress("hpf",&hpf);
   nnt->SetBranchAddress("limiter",&limiter);
   nnt->SetBranchAddress("coneAng",&coneang);
   nnt->SetBranchAddress("bIce",&bice);
   // to look up waveform for EAng, HAng
   nnt->BuildIndex("EAng + (1000*HAng)","coneAng");
   // find the max angles
   Printf("finding allowed angles...");
   std::set<Float_t> Eangs, Hangs, Cangs;
   const Long64_t nnents = nnt->GetEntries();
   for (Long64_t i=0; i<nnents; ++i) {
      nnt->GetEntry(i);
      Eangs.insert(eang);
      Hangs.insert(hang);
      Cangs.insert(coneang);
   }
#ifdef DEBUG
   std::set<Float_t>::const_iterator ang, end = Eangs.end();
   Printf("EAngs:");
   for (ang=Eangs.begin(); ang!=end; ++ang) {
      Printf("%g",*ang);
   }
   Printf("HAngs:");
   for (ang=Hangs.begin(), end=Hangs.end(); ang!=end; ++ang) {
      Printf("%g",*ang);
   }
   Printf("ConeAngs:");
   for (ang=Cangs.begin(), end=Cangs.end(); ang!=end; ++ang) {
      Printf("%g",*ang);
   }
#endif
   
   Float_t theta(0), phi(0), cone(0);
   Float_t EAng[NSnConstants::kNchans], 
           HAng[NSnConstants::kNchans];
   Float_t CAng(0);
   TSnCalWvData* evdat = new TSnCalWvData;
   TSnEventMetadata* meta = new TSnEventMetadata;
   TSnEventHeader* hdr = new TSnEventHeader;
   //ot = nnt->CloneTree(0);
   //ot->SetName("SimTemplEvts");
   ot = new TTree("SimTemplEvts","simulated events from templates",1);
   ot->SetDirectory(outf);
   ot->Branch("EventMetadata.",&meta);
   ot->Branch("EventHeader.",&hdr);
   ot->Branch("EAng",&(EAng[0]),Form("EAng[%hhu]/F",NSnConstants::kNchans));
   ot->Branch("HAng",&(HAng[0]),Form("HAng[%hhu]/F",NSnConstants::kNchans));
   ot->Branch("CAng",&CAng,"CAng/F");
   ot->Branch("theta",&theta,"theta/F");
   ot->Branch("phi",&phi,"phi/F");
   ot->Branch("NuData.",&evdat);
   // some useful aliases
   TString an;
   for (UChar_t ch=0; ch<NSnConstants::kNchans; ++ch) {
      // to use as a cut for a particular channel:
      an = Form("Ch%d",ch);
      ot->SetAlias(an.Data(),
                   Form("(Iteration$>=(%hhu*%hhu)) && (Iteration$<(%hhu*%hhu))",
                        NSnConstants::kNsamps, ch,
                        NSnConstants::kNsamps,
                        static_cast<UChar_t>(ch+1)));
      // to use as a variable showing the sample number [0,127] for any chan
      an = Form("SmpCh%d",ch);
      ot->SetAlias(an.Data(),
                   Form("Iteration$-%u", static_cast<UInt_t>(ch)
                        *static_cast<UInt_t>(NSnConstants::kNsamps)));
      // e.g. Draw("RawData.fData:SmpCh2","EventHeader.fNum==21 && Ch2","l")
   }

   Printf("generating events...");
   TStopwatch timer;
   timer.Start();
   
   for (UInt_t i=0; i<simevts; ++i) {
      
      if ( (i%1000)==0 ) {
         fprintf(stderr,"Processing %u/%u ...            \r",i,simevts);
      }
      
      // choose angles
      theta = (thetaOpt>360.) ? TMath::ACos( rnd.Uniform(-1.0, 0.0) ) 
                              : thetaOpt * TMath::DegToRad();
      phi   = (phiOpt>360.) ? rnd.Uniform(0.0, TMath::TwoPi())
                            : phiOpt * TMath::DegToRad();
      cone  = (coneOpt>360.) 
         ? rnd.Uniform(*(Cangs.begin()), *(Cangs.rbegin()))
         : coneOpt; // leave this one in degrees (as in the tree)
      CAng = findNearestAllowedAngle(Cangs, cone);
      
#ifdef DEBUG
      Printf("--- theta=%g, phi=%g, cone=%g",
             theta*TMath::RadToDeg(), phi*TMath::RadToDeg(), cone);
#endif
      
      // calculate channel shifts
      TArrayD pwdt = NSnChanCorl::GetPlaneWaveOffsets(theta,
                                                      phi,
                                                      zeros,
                                                      pos,
                                                      kNgTopFirn);
      TVector3 dir;
      dir.SetMagThetaPhi(1.0, theta, phi);
      
#ifdef DEBUG
      TObjArray graphs;
      graphs.SetOwner(kTRUE);
      TCanvas* c1 = new TCanvas("c1","c1",800,700);
      c1->Divide(2,2);
#endif
      
      for (UChar_t ch=0; ch<NSnConstants::kNchans; ++ch) {
         
         // look up the EAng, fhang for this antenna
         Float_t feang(0), fhang(0);
         findEangHang(nvec[ch], dir, feang, fhang);
         feang  = TMath::Abs(TVector2::Phi_mpi_pi(feang));
         fhang  = TMath::Abs(TVector2::Phi_mpi_pi(fhang));
         feang *= TMath::RadToDeg();
         fhang *= TMath::RadToDeg();
         // find closest allowed angle
         EAng[ch] = findNearestAllowedAngle(Eangs, feang);
         HAng[ch] = findNearestAllowedAngle(Hangs, fhang);
         const Long64_t ni = 
            nnt->GetEntryNumberWithIndex(EAng[ch] + (1000*HAng[ch]), CAng);
#ifdef DEBUG
         Printf("EAng=%g (%g), HAng=%g (%g), CAng=%g, ni=%lld",
                EAng[ch],feang,HAng[ch],fhang,CAng,ni);
#endif
         if (ni>-1) {
            nnt->GetEntry(ni);
#ifdef DEBUG
            c1->cd(ch+1);
            TGraph* och = wave->NewGraphForChan(0, kTRUE);
            const Int_t ochnp = och->GetN();
            Double_t* ochy = och->GetY();
            for (Int_t k=0; k<ochnp; ++k, ++ochy) {
               *ochy *= norm;
            }
            graphs.Add(och);
            och->SetLineColor(kBlack);
            och->SetMarkerColor(kBlack);
            och->SetMarkerStyle(7);
            och->Draw("apl");
#endif
            
            // first calculate the shift between chans due to the angle
            // ch0 is always unshifted; other chans shifted w.r.t. ch0
            // jitter the shift by the specified timing resolution
            const Double_t shift = 
               rnd.Gaus( (ch==0) ? 0.0
                            : -pwdt.At( TSnRecoChanOffsets::IndexFor(ch, 0) ),
                         timereso);
            // get a graph of the waveform
            // data only in channel 0 of the template
            TGraph* gch = wave->NewGraphForChan(0, kTRUE);
            // "fit" the graph with an spline interpolation
            TSpline3* gsp = new TSpline3("stmp", gch);
            // evaluate the spline at the new sample positions
            // (shifted, but NOT wrapped)
            // and save that into the event data waveform
            Float_t* d = evdat->GetData(ch);
            const Float_t tstep = 1.0 / NSnConstants::kSampRate;
            const Float_t tlast = static_cast<Float_t>(NSnConstants::kNsamps-1)
               / NSnConstants::kSampRate;
            Float_t xloc = shift;
            for (UChar_t s=0; s<NSnConstants::kNsamps; ++s, ++d, xloc+=tstep) {
               if ( (xloc<0.0) || (xloc>=tlast) ) {
                  *d = 0.0;
               } else {
                  *d = gsp->Eval( xloc );
               }
            }
#ifdef DEBUG
            Printf("ch%hhu: shift=%g, dt=%g", ch, shift,
                   (ch==0) ? 0.0
                   : pwdt.At( TSnRecoChanOffsets::IndexFor(ch, 0) ));
            
            TGraph* fch = evdat->NewGraphForChan(ch, kTRUE);
            Double_t* y = gch->GetY();
            Double_t* fy = fch->GetY();
            for (UChar_t s=0; s<NSnConstants::kNsamps; ++s, ++y, ++fy) {
               *y *= norm;
               *fy *= norm;
            }
            
            gch->SetLineColor(kRed+1);
            gch->SetMarkerColor(kRed+1);
            gch->SetMarkerStyle(7);
            gch->Draw("pl");
            
            delete gsp;
            gsp = new TSpline3("stmp",gch);
            gsp->SetLineColor(kAzure-6);
            gsp->SetMarkerColor(kAzure-6);
            gsp->SetMarkerStyle(7);
            gsp->Draw("pl same");
            
            graphs.Add(fch);
            fch->SetLineColor(kOrange+7);
            fch->SetMarkerColor(kOrange+7);
            fch->SetMarkerStyle(7);
            fch->Draw("pl");
#endif


            d = evdat->GetData(ch);
            // finally add noise to the waveform
            for (UChar_t s=0; s<NSnConstants::kNsamps; ++s, ++d) {
               *d = rnd.Gaus( (*d) * norm, noise );
            }
            
#ifdef DEBUG
            TGraph* nch = evdat->NewGraphForChan(ch, kTRUE);
            graphs.Add(nch);
            nch->SetLineColor(kGreen+2);
            nch->SetMarkerColor(kGreen+2);
            nch->SetMarkerStyle(7);
            nch->Draw("pl");
#endif
            
            // cleanup
#ifdef DEBUG
            graphs.Add(gch);
            graphs.Add(gsp);
#else
            delete gch;
            delete gsp;
#endif
         }

      } // end channel loop

#ifdef DEBUG
      TObject* o(0);
      while ( (o=c1->WaitPrimitive())!=0 ) {
         gSystem->ProcessEvents();
      }
      delete c1;
#endif
         
         // save this event
         ot->Fill();
         
   } // end event loop

   fprintf(stderr,"\n");

   timer.Stop();
   Printf("Finished generating events in:");
   timer.Print();
   
   outf->Write();
   
   Printf("Wrote [%s]",outf->GetName());
   
   delete outf; outf=0; // close file
}
コード例 #8
0
SimulationOutput* LightSimulator::Run(){
    
  TRandom3 randgen = TRandom3(0);

  if (debug) cout << ntoys*nrays << " light propagations to simulate" << endl;

  long counter_ray=0;

  if (output) delete output;
  output = new SimulationOutput(deposit);
    
  if (!isinsideboundaries()) return output;

  for (int nrun = 0; nrun<ntoys; nrun++){
            
    vector<Int_t> myphotons(4,0);

    for (int nray = 0; nray<nrays; nray++){

      counter_ray++;
      //	if (counter_ray%(ntoys*nrays/10)==0) cout << "Done " << counter_ray << " rays" << endl;

      Double_t phi = randgen.Uniform(-Pi(),Pi());
      Double_t costheta = randgen.Uniform(-1,1);
      TVector3 dir; dir.SetMagThetaPhi(1,ACos(costheta),phi);
      LightRay lr(deposit.position,dir);

      bool matched = false;
      Int_t matchx = 999;
      Int_t matchy = 999;
      Int_t firstmatchx = 999;
      Int_t firstmatchy = 999;

      Int_t index=0;
      MatchObject m;
      vector<MatchObject> matches;
      while (index>=0 && index<pars.max_distance_unit_propagation && index<Max(firstmatchx,firstmatchy)){
	if (propray(lr,kNS,index,matchx,m)){
	  if (!matched) firstmatchx=matchx;
	  matched=true;
	  matches.push_back(m);
	}
	if (propray(lr,kEW,index,matchy,m)){
	  if (!matched) firstmatchy=matchy;
	  matched=true;
	  matches.push_back(m);
	}
	index++;
      }

      vector<GoodMatchObject> goodmatches=convert_matches(matches);
	
      Double_t pathxy = pars.max_distance_unit_propagation*10*pars.xtalsize;
      GoodMatchObject finalmatch;
      for (size_t i=0; i<goodmatches.size(); i++){
	Double_t path = sqrt(pow(goodmatches[i].positionx-lr.origin.x(),2)+pow(goodmatches[i].positiony-lr.origin.y(),2));
	if (path<pathxy) {pathxy=path; finalmatch=goodmatches[i];}
      }
      if (pathxy>1e4){
	if (debug) cout << "LOOPER" << endl;
	continue;
      }

      Int_t channel = findchannel(finalmatch.x,finalmatch.y)-1;
     
      if (debug) cout << finalmatch.x << " " << finalmatch.y << " " << pathxy << " " << channel+1 << endl;

      Double_t path3d = pathxy/Sin(lr.dirvect.Theta());
     
      TVector3 rotated_origin_xy = lr.origin; rotated_origin_xy.SetZ(0);
      TVector3 rotated_impact = TVector3(finalmatch.positionx,finalmatch.positiony,0);
      TRotation r;
      r.RotateZ(-Pi()/4);
      rotated_origin_xy = r*rotated_origin_xy;
      rotated_impact = r*rotated_impact;

      Int_t nx = 0;
      Int_t ny = 0;
      Int_t nz = 0;
      {
	Int_t sx = finalmatch.x+finalmatch.y;
	if (sx==0) nx=0;
	else if (sx>0) nx = sx/2-1;
	else nx = TMath::Abs(sx)/2;
	Int_t dy = finalmatch.y-finalmatch.x;
	if (dy==0) ny=0;
	else if (dy>0) ny = dy/2-1;
	else ny = TMath::Abs(dy)/2;
	Float_t finalz = path3d*Cos(lr.dirvect.Theta())+deposit.position.z()-pars.xtalheight/2;
	nz = Int_t((fabs(finalz)+pars.xtalheight/2)/pars.xtalheight);
      }
      Int_t all_crossings = nx+ny+nz;

      Int_t my_paper_refl = 0;

      TVector2 difference = TVector2(fabs(rotated_origin_xy.x()-rotated_impact.x()),fabs(rotated_origin_xy.y()-rotated_impact.y()));
      if (difference.Phi()<limit_angle) my_paper_refl+=nx;
      if (Pi()/2-difference.Phi()<limit_angle) my_paper_refl+=ny;
      if (lr.dirvect.Theta()<limit_angle) my_paper_refl+=nz;

      Double_t att_absorption_point = randgen.Exp(pars.light_att_length);
      if (path3d>att_absorption_point) continue;

      Double_t prob_loss_in_reflections = pow(pars.eff_reflection_paper,my_paper_refl)*pow(pars.eff_reflection_total,all_crossings-my_paper_refl);
      if (randgen.Uniform()>prob_loss_in_reflections*pars.eff_lightcoll) continue;
	
      Double_t scintillation_delay = randgen.Exp(pars.scintillation_typ_timescale);

      Double_t arrival_time = deposit.time+path3d/pars.speed_of_light+scintillation_delay;
      if (arrival_time>pars.limit_arrival_time) continue;

      myphotons.at(channel)++;
      output->chamfer_pulseshape[channel]->Fill(arrival_time);
      output->reflections_paper->Fill(my_paper_refl);
      output->reflections_total->Fill(all_crossings-my_paper_refl);
      output->reflections_all->Fill(all_crossings);
      output->optical_path->Fill(path3d);
	
    }

    for (int i=0; i<4; i++) output->chamfer_photons[i]->Fill(myphotons[i]);

  }

  for (int i=0; i<4; i++) Normalize(output->chamfer_pulseshape[i]);
  Normalize(output->reflections_paper);
  Normalize(output->reflections_total);
  Normalize(output->reflections_all);
  Normalize(output->optical_path);

  return output;

};
コード例 #9
0
ファイル: DaviesCotton.C プロジェクト: ROBAST/ROBAST
void RayTrace(AOpticsManager* manager, TCanvas* can3D)
{
  const int kNdeg = 8;
  TH2D* h2[kNdeg];
  TGraph* graph = new TGraph();
  TCanvas* can = new TCanvas("can", "can", 900, 900);
  TCanvas* can2= new TCanvas("can2", "can2", 900, 900);
  can->Divide(3, 3, 1e-10, 1e-10);

  TH2D* hMirror = new TH2D("hMirror", ";X (mm);Y (mm)", 1000, -7, 7, 1000, -7, 7);

  for(int i = 0; i < kNdeg; i++){

    double deg = i*0.5;
    TGeoTranslation raytr("raytr", -2*kF*TMath::Sin(deg*TMath::DegToRad()), 0, 2*kF*TMath::Cos(deg*TMath::DegToRad()));
    TVector3 dir;
    dir.SetMagThetaPhi(1, TMath::Pi() - deg*TMath::DegToRad(), 0);
    double lambda = 400*nm; // dummy
    ARayArray* array = ARayShooter::Square(lambda, 14*m, 401, 0, &raytr, &dir);

    manager->TraceNonSequential(*array);

    h2[i] = new TH2D("", Form("#it{#theta} = %3.1f#circ;x (mm); y (mm)", deg), 200, -40, 100, 200, -70, 70);
    TH2D tmp("", "", 100, -1e5, 1e5, 100, -1e5, 1e5);

    TObjArray* focused = array->GetFocused();

    for(Int_t j = 0; j <= focused->GetLast(); j++){
      ARay* ray = (ARay*)(*focused)[j];
      Double_t p[4];
      ray->GetLastPoint(p);
      tmp.Fill(p[0], p[1]);

      if (i == 0) {
        int n = ray->FindNodeNumberStartWith("mirror");
        const double* pn = ray->GetPoint(n);
        hMirror->Fill(pn[0]/m, pn[1]/m);
      } // if

      if (i == kNdeg - 1 && gRandom->Uniform() < 0.001) {
        TPolyLine3D* pol = ray->MakePolyLine3D();
        pol->SetLineColor(2);
        can3D->cd();
        pol->Draw();
      } // if
    } // j

    double meanx = tmp.GetMean();

    for(Int_t j = 0; j <= focused->GetLast(); j++){
      ARay* ray = (ARay*)(*focused)[j];
      Double_t p[4];
      ray->GetLastPoint(p);
      h2[i]->Fill((p[0] - meanx)/mm, p[1]/mm);
    } // j

    can->cd(i + 1);
    h2[i]->Draw("colz");

    if(i == 0){
      can2->cd();
      hMirror->Draw("colz");
    } // i

    delete array;
  } // i
}
コード例 #10
0
ファイル: noAveBounceStdy.C プロジェクト: jetatar/snowShovel
TGraph* newShiftChi2Graph(const T* const dat1,
                          const Int_t    nd1,
                          const U* const dat2,
                          const Int_t    nd2,
                          const Int_t    minbin=-1,   // -1 => 0
                          const Int_t    maxbin=-1,   // -1 => nd1-1
                          const Bool_t   useSqrtErrs=kFALSE) {
   const Int_t minb = (minbin<0) ?     0 : minbin;
   const Int_t maxb = (maxbin<0) ? nd1-1 : maxbin;
   if ( (maxb<=minb) || (maxb>=nd1) || (maxb>=nd2) ) {
      Fatal("newShiftChi2Graph",
            "Invalid maxb=%d. (minb=%d, nd1=%d, nd2=%d)",
            maxb, minb, nd1, nd2);
   }
   const T* c1 = dat1;
   const U* c2 = dat2;
   Int_t pos, j(0);
   const Int_t ndh = (maxb-minb+1)/2;
   TGraphErrors* gc = new TGraphErrors;
   for (Int_t sh=1-ndh; sh<ndh; ++sh) {
      Double_t x=0, t=0, cmp=0;
      c1 = dat1+minb;
      c2 = dat2+minb-sh;

      for (Int_t i=minb; i<=maxb; ++i, ++c1, ++c2) {
         pos = c2 - dat2;
#ifdef SHIFT_INTO_WINDOW
         if (pos<nd2) {
            if (pos>=0) {
#else
         if (pos<=maxb) {
            if (pos>=minb) {
#endif
               t  = (*c1) - (*c2);
               t *= t;
               if (useSqrtErrs) {
                  t /= TMath::Abs(static_cast<Double_t>(*c2));
               }
               x += t;
               cmp += 1.0;
            }
         } else {
            break;
         }
      }
      if (cmp>1.0) {
         x /= cmp-1.0;

         gc->SetPoint(j, static_cast<Double_t>(sh), x);
         
         ++j;
      }
   }

   return gc;
}



void noAveBounceStdy(const Char_t* rtfn,
                     const Char_t* wvfn,
                     const Char_t* FPNfn,
                     const Char_t* outfn,
                     const Int_t   fitType=0,
                     const Int_t   fitOpt=0,
                     const Char_t* minner="Minuit2",
                     const Char_t* algo="Migrad",
                     const Int_t   shiftminb=-1,
                     const Int_t   shiftmaxb=-1,
                     const Bool_t  applyFilter=kTRUE) {
   // fitType:
   //   0 = fit theta phi with getShiftLL
   //   5 = fit theta phi with getShiftChi2
   //  20 = fit 3 deltaT's; use contraints for other 3
   //
   // fitOpt:
   //   0 = fit (filtered) waveforms
   //  10 = fit envelope of (filtered) waveforms
   //
   //     minner              algo
   //  Minuit /Minuit2        Migrad,Simplex,Combined,Scan  (default is Migrad)
   //  Minuit2                Fumili2
   //  Fumili
   //  GSLMultiMin            ConjugateFR, ConjugatePR, BFGS, 
   //                         BFGS2, SteepestDescent
   //  GSLMultiFit
   //  GSLSimAn
   //  Genetic

   if (mini==0) {
      mini = ROOT::Math::Factory::CreateMinimizer(minner, algo);
      mini->SetMaxFunctionCalls(1000000);
      mini->SetMaxIterations(10000);
      mini->SetTolerance(0.001);
      mini->SetPrintLevel(0);
   }

   nt = new TChain("runtree");
   nt->Add(rtfn);

   const Long64_t nents = nt->GetEntries();
   if (nents==0) {
      Error("noAveBunceStdy","No events in tree from [%s].",rtfn);
      return;
   }

   ns = new TChain("nShifts");
   ns->Add(wvfn);

   if (nents>ns->GetEntries()) {
      Error("bounceStudy","%lld entries in runtree but "
            "%lld entries in shift tree",nents,ns->GetEntries());
      return;
   }
   
   fpnf = TFile::Open(FPNfn);
   if ( (fpnf==0) || (fpnf->IsZombie()) ) {
      Error("bounceStudy","Could not open FPN file [%s]",FPNfn);
      return;
   }
   for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
      gPed[ch]   = dynamic_cast<TGraphErrors*>(
         fpnf->Get(Form("gExlPed_ch%d",ch)));
      gNoise[ch] = dynamic_cast<TGraphErrors*>(
         fpnf->Get(Form("gExlRms_ch%d",ch)));
      if ( (gPed[ch]==0) || (gNoise[ch]==0) ) {
         Error("bounceStudy",
               "Couldn't get FPN/noise graphs from [%s]",FPNfn);
         return;
      }
   }

   // read from tree into...
   Float_t  pedsubs[NSnConstants::kNchans][NSnConstants::kNsamps];
   Float_t  psshift[NSnConstants::kNchans][NSnConstants::kNsamps];
   Float_t  filtered[NSnConstants::kNchans][NSnConstants::kNsamps];
   Float_t  envelope[NSnConstants::kNchans][NSnConstants::kNsamps];
   UShort_t samples[NSnConstants::kNchans][NSnConstants::kNsamps];
   UInt_t   evnum, utime, utimeus, mbchksum;
   
   nt->SetBranchAddress("mbChecksum",&mbchksum);
   nt->SetBranchAddress("EvtNum",&evnum);
   nt->SetBranchAddress("unixTime",&utime);
   nt->SetBranchAddress("unixTimeUS",&utimeus);
   for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
      nt->SetBranchAddress(Form("data%02d",ch), &(samples[ch][0]));
   }

   // shift for stop tree
   Int_t nsent;
   UInt_t nsevn;
   Int_t aveShift(0), aveLen(0);
   Int_t shift[NSnConstants::kNchans];
   Int_t len[NSnConstants::kNchans];
   ns->SetBranchAddress("Ent",&nsent);
   ns->SetBranchAddress("EvtNum",&nsevn);
   for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
      ns->SetBranchAddress(Form("shift%02d",ch),&(shift[ch]));
      ns->SetBranchAddress(Form("len%02d",ch),&(len[ch]));
   }
   ns->BuildIndex("EvtNum");

   // output
   TString hn;
   outf = TFile::Open(outfn,"recreate");

   if (fitType==20) {
      hn = "EvtNum:";
      for (Int_t i=1; i<NSnConstants::kNchans; ++i) {
         hn += Form("dt%d%d:",i,i-1);
      }
      hn += "chi2";
      tChanDTsFit = new TNtuple("tChanDTsFit",
                                "fit of channel dts",
                                hn.Data());
   } else {
      tThetaPhiFit = new TNtuple("tThetaPhiFit","theta phi fit tree",
                                 "EvtNum:theta:phi:chi2");
   }


   for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
      for (Int_t xc=0; xc<ch; ++xc) {
         hn = Form("hFiltCorrCoefShiftVsEvt_ch%02d_ch%02d",ch,xc);
         hFiltCorrCoefShiftVsEvt[ch][xc] = new TH2F(hn.Data(),
              Form("corr coef for offset between ch%d and ch%d of filtered "
                   "wvfms vs event;event;offset (ch%d-ch%d);correlation coef",
                   ch,xc,ch,xc),
                                          nents, -0.5, nents-0.5,
                                          NSnConstants::kNsamps,
                                          1-(NSnConstants::kNsamps/2)-0.5,
                                          (NSnConstants::kNsamps/2)+0.5);
         hFiltCorrCoefShiftVsEvt[ch][xc]->SetDirectory(outf);

         hn = Form("hFiltShiftChi2VsEvt_ch%02d_ch%02d",ch,xc);
         hFiltShiftChi2VsEvt[ch][xc] = new TH2F(hn.Data(),
              Form("#chi^{2} of offset between ch%d and ch%d of filtered "
                   "wvfms vs event;event;offset (ch%d-ch%d);#chi^{2}",
                   ch,xc,ch,xc),
                                          nents, -0.5, nents-0.5,
                                          NSnConstants::kNsamps,
                                          1-(NSnConstants::kNsamps/2)-0.5,
                                          (NSnConstants::kNsamps/2)+0.5);
         hFiltShiftChi2VsEvt[ch][xc]->SetDirectory(outf);
      }
   }

   Long64_t ne(0);
   for (Long64_t ev=0; ev<nents; ++ev) {
   //for (Long64_t ev=0; ev<250; ++ev) {
      if ( (ev%500)==0 ) {
         fprintf(stderr,"Processing %lld / %lld  (%02.2f%%)            \r",
            ev, nents,
            100.*static_cast<Float_t>(ev)/static_cast<Float_t>(nents));
      }
      nt->GetEntry(ev);
      ne = ns->GetEntryNumberWithIndex(evnum);
      if (ne>-1) {
         ns->GetEntry(ne);

         // find the stop shift
         aveShift = aveLen = 0;
         for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
            aveShift += shift[ch];
            aveLen   += len[ch];
         }
         aveShift = TMath::Nint( static_cast<Float_t>(aveShift)/
                                 static_cast<Float_t>(NSnConstants::kNchans) );
         aveLen   = TMath::Nint( static_cast<Float_t>(aveLen)/
                                 static_cast<Float_t>(NSnConstants::kNchans) );
         const Int_t shiftStart = NSnConstants::kNsamps-1 - aveShift - aveLen;
         for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
            // subtract FPN
            const Double_t* pd = gPed[ch]->GetY();
            const UShort_t* sp = &(samples[ch][0]);
            Float_t*        ps = &(pedsubs[ch][0]);
            Float_t*        ph = &(psshift[ch][ shiftStart ]);
            for (Int_t sm=0; sm<NSnConstants::kNsamps;
                                  ++sm, ++pd, ++sp, ++ps, ++ph) {
               *ps = *sp - *pd;
               while ( (ph-&(psshift[ch][0])) >= NSnConstants::kNsamps) {
                  ph -= NSnConstants::kNsamps;
               }
               *ph = *ps;
            }
            
            // apply filter
            memcpy(&(filtered[ch][0]), &(psshift[ch][0]),
                   NSnConstants::kNsamps*sizeof(Float_t));
            if (applyFilter) {
               filterWaveform(&(filtered[ch][0]), NSnConstants::kNsamps);
            }
            // find envelope
            memcpy(&(envelope[ch][0]), &(filtered[ch][0]),
                   NSnConstants::kNsamps*sizeof(Float_t));
            TSnSpectral::EnvelopeReal(&(envelope[ch][0]), NSnConstants::kNsamps);

#ifdef DEBUG_SHIFTS
            TCanvas* cdbgsh = new TCanvas;
            cdbgsh->cd();
            Float_t xsm[NSnConstants::kNsamps], rsmp[NSnConstants::kNsamps];
            for (Int_t i=0; i<NSnConstants::kNsamps; ++i) {
               xsm[i] = i;
               rsmp[i] = samples[ch][i];
            }
            TGraph* gsmp = new TGraph(NSnConstants::kNsamps, xsm, rsmp);
            TGraph* gps  = new TGraph(NSnConstants::kNsamps, xsm, 
                                      &(pedsubs[ch][0]));
            TGraph* gph  = new TGraph(NSnConstants::kNsamps, xsm,
                                      &(psshift[ch][0]));
            TGraph* gfl  = new TGraph(NSnConstants::kNsamps, xsm,
                                      &(filtered[ch][0]));
            TGraph* gen  = new TGraph(NSnConstants::kNsamps, xsm,
                                      &(envelope[ch][0]));
            gsmp->SetMarkerStyle(7);
            gsmp->SetMarkerColor(kBlack);
            gsmp->SetLineColor(kBlack);
            gps->SetMarkerStyle(7);
            gps->SetMarkerColor(kRed);
            gps->SetLineColor(kRed);
            gph->SetMarkerStyle(7);
            gph->SetMarkerColor(kAzure-7);
            gph->SetLineColor(kAzure-7);
            gfl->SetMarkerStyle(7);
            gfl->SetMarkerColor(kGreen+2);
            gfl->SetLineColor(kGreen+2);
            gen->SetMarkerStyle(7);
            gen->SetMarkerColor(kViolet-1);
            gen->SetLineColor(kViolet-1);
            gsmp->SetMinimum(-1500);
            gsmp->SetMaximum(2500);
            Printf("ch%d: shift=%d, len=%d",
                   ch, shift[ch], len[ch]);
            gsmp->Draw("apc");
            gps->Draw("pc");
            gph->Draw("pc");
            gfl->Draw("pc");
            gen->Draw("pc");
            cdbgsh->WaitPrimitive();
            delete gsmp; delete gps; delete gph; delete gfl; delete gen;
            delete cdbgsh;
#endif
         }
         
         if (shiftmaxb!=shiftminb) {
            maxdt = (shiftmaxb - shiftminb) / (2.0*kSmpRate);
         } else {
            maxdt =  NSnConstants::kNsamps  / (2.0*kSmpRate);
         }
         
         const Float_t* chdat(0), * xcdat(0);
         for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
            if (fitOpt==0) {
               chdat = &(filtered[ch][0]);
            } else if (fitOpt==10) {
               chdat = &(envelope[ch][0]);
            } else {
               Fatal("noAveBounceStdy","Unknown fitOpt [%d]",fitOpt);
            }
            for (Int_t xc=0; xc<ch; ++xc) {
               if (fitOpt==0) {
                  xcdat = &(filtered[xc][0]);
               } else if (fitOpt==10) {
                  xcdat = &(envelope[xc][0]);
               } else {
                  Fatal("noAveBounceStdy","Unknown fitOpt [%d]",fitOpt);
               }
               gcor[ch][xc] = newCorrCoefGraph(chdat,
                                               xcdat,
                                               NSnConstants::kNsamps,
                                               shiftminb,
                                               shiftmaxb);
               gspl[ch][xc] = new TSpline3(Form("spl_%d_%d",ch,xc),
                                           gcor[ch][xc]);
               gchi[ch][xc] = newShiftChi2Graph(chdat,
                                                NSnConstants::kNsamps,
                                                xcdat,
                                                NSnConstants::kNsamps,
                                                shiftminb,
                                                shiftmaxb);
               gspc[ch][xc] = new TSpline3(Form("spc_%d_%d",ch,xc),
                                           gchi[ch][xc]);

#ifdef DEBUG_CORRELS
            TCanvas* cdbgcl = new TCanvas("cdbgcl","cdbgcl",800,1000);
            cdbgcl->Divide(1,3);
            cdbgcl->cd(1);
            Float_t xxsm[NSnConstants::kNsamps];
            for (Int_t i=0; i<NSnConstants::kNsamps; ++i) {
               xxsm[i] = i;
            }
            TGraph* gcfl  = new TGraph(NSnConstants::kNsamps, xxsm,
                                       &(filtered[ch][0]));
            TGraph* gxfl  = new TGraph(NSnConstants::kNsamps, xxsm,
                                       &(filtered[xc][0]));
            TGraph* gcen  = new TGraph(NSnConstants::kNsamps, xxsm,
                                       &(envelope[ch][0]));
            TGraph* gxen  = new TGraph(NSnConstants::kNsamps, xxsm,
                                       &(envelope[xc][0]));
            gcfl->SetMarkerStyle(7);
            gcfl->SetMarkerColor(kBlack);
            gcfl->SetLineColor(kBlack);
            gxfl->SetMarkerStyle(7);
            gxfl->SetMarkerColor(kRed);
            gxfl->SetLineColor(kRed);
            gcen->SetMarkerStyle(7);
            gcen->SetMarkerColor(kGray);
            gcen->SetLineColor(kGray);
            gxen->SetMarkerStyle(7);
            gxen->SetMarkerColor(kViolet-1);
            gxen->SetLineColor(kViolet-1);
            gcfl->Draw("apc");
            gxfl->Draw("pc");
            gcen->Draw("pc");
            gxen->Draw("pc");
            cdbgcl->cd(2);
            gspl[ch][xc]->SetMarkerStyle(7);
            gspl[ch][xc]->SetMarkerColor(kAzure-7);
            gspl[ch][xc]->SetLineColor(kAzure-7);
            gspl[ch][xc]->Draw("pc");
            cdbgcl->cd(3);
            gspc[ch][xc]->SetMarkerStyle(7);
            gspc[ch][xc]->SetMarkerColor(kViolet-6);
            gspc[ch][xc]->SetLineColor(kViolet-6);
            gspc[ch][xc]->Draw("pc");
            cdbgcl->cd();
            cdbgcl->Update();
            cdbgcl->WaitPrimitive();
            delete gcfl; delete gxfl; delete cdbgcl;
            delete gcen; delete gxen;
#endif

               const Int_t gn = gcor[ch][xc]->GetN();
               const Double_t* gx = gcor[ch][xc]->GetX(),
                             * gy = gcor[ch][xc]->GetY(),
                             * cx = gchi[ch][xc]->GetX(),
                             * cy = gchi[ch][xc]->GetY();
               for (Int_t k=0; k<gn; ++k, ++gx, ++gy, ++cx, ++cy) {
                  hFiltCorrCoefShiftVsEvt[ch][xc]->Fill(ev, *gx, *gy);
                  hFiltShiftChi2VsEvt[ch][xc]->Fill(ev, *cx, *cy);
               }

            }
         }
         
         if (fitType==20) {
            // fit for the best, consistent time offsets
            mini->Clear();
            ROOT::Math::Functor f(&getDeltaTsLL, NSnConstants::kNchans-1);
            mini->SetFunction(f);
            for (Int_t ch=1; ch<NSnConstants::kNchans; ++ch) {
               if (strcmp(minner,"Genetic")==0) {
                  mini->SetLimitedVariable(ch-1, 
                                           Form("dt%d%d",ch,ch-1), 0, 0.01,
                                           -maxdt, maxdt);
               } else {
                  mini->SetVariable(ch-1, Form("dt%d%d",ch,ch-1), 0, 0.01);
               }
            }
            mini->Minimize();
            const Double_t* result = mini->X();
            const Double_t* rs = result;
            Float_t* tofil = new Float_t[NSnConstants::kNchans+2];
            Float_t* tf = tofil;
            *tf++ = ev;
            for (Int_t ch=1; ch<NSnConstants::kNchans; ++ch, ++tf, ++rs) {
               *tf = *rs;
            }
            *tf = mini->MinValue();
            tChanDTsFit->Fill(tofil);
            delete[] tofil;
#ifdef DEBUG_DTS
            for (Int_t ch=1; ch<NSnConstants::kNchans; ++ch) {
               Printf("result[%d]=%g",ch-1,result[ch-1]);
            }
            TCanvas* cdbgdt = new TCanvas("cdbgdt","cdbgdt",1000,1000);
            cdbgdt->Divide(2,3);
            Float_t xxsm[NSnConstants::kNsamps];
            for (Int_t i=0; i<NSnConstants::kNsamps; ++i) {
               xxsm[i] = i;
            }

            TGraph* gorg[NSnConstants::kNchans];
            TGraph* gocp[NSnConstants::kNchans];
            TGraph* goen[NSnConstants::kNchans];
            TGraph* gshf[NSnConstants::kNchans][NSnConstants::kNchans];
            TGraph* gshe[NSnConstants::kNchans][NSnConstants::kNchans];
            for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
               gorg[ch] = new TGraph(NSnConstants::kNsamps, xxsm,
                                     &(filtered[ch][0]));
               gocp[ch] = new TGraph(NSnConstants::kNsamps, xxsm,
                                     &(filtered[ch][0]));
               goen[ch] = new TGraph(NSnConstants::kNsamps, xxsm,
                                     &(envelope[ch][0]));
               for (Int_t xc=0; xc<ch; ++xc) {
                  Double_t dt=0;
                  for (Int_t i=(ch-xc); i>0; --i) {
                     dt += result[ch-i];
                  }
                  dt *= kSmpRate; // convert to samples
                  Printf("dt[%d][%d]=%g",ch,xc,dt);
                  gshf[ch][xc] = new TGraph(NSnConstants::kNsamps);
                  gshe[ch][xc] = new TGraph(NSnConstants::kNsamps);
                  for (Int_t i=0; i<NSnConstants::kNsamps; ++i) {
                     gshf[ch][xc]->SetPoint(i, xxsm[i]+dt, filtered[xc][i]);
                     gshe[ch][xc]->SetPoint(i, xxsm[i]+dt, envelope[xc][i]);
                  }
                  gshf[ch][xc]->SetMarkerStyle(7);
                  gshf[ch][xc]->SetLineColor(kRed);
                  gshf[ch][xc]->SetMarkerColor(kRed);
                  gshe[ch][xc]->SetMarkerStyle(7);
                  gshe[ch][xc]->SetLineColor(kViolet-1);
                  gshe[ch][xc]->SetMarkerColor(kViolet-1);
               }
               gorg[ch]->SetMarkerStyle(7);
               gorg[ch]->SetLineColor(kBlack);
               gorg[ch]->SetMarkerColor(kBlack);
               goen[ch]->SetMarkerStyle(7);
               goen[ch]->SetLineColor(kGray);
               goen[ch]->SetMarkerColor(kGray);
               gocp[ch]->SetMarkerStyle(7);
               gocp[ch]->SetLineStyle(7);
               gocp[ch]->SetLineColor(kGreen+2);
               gocp[ch]->SetMarkerColor(kGreen+2);
            }
            gStyle->SetOptStat(0);
            Int_t pp=0;
            for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
               for (Int_t xc=0; xc<ch; ++xc) {
                  cdbgdt->cd(++pp);
                  hn = Form("hd_%d_%d",ch,xc);
                  TH2F* hd = new TH2F(hn.Data(),
                                      Form("black=ch%d, red/green=ch%d;"
                                           "sample;ADC",ch,xc),
                                      NSnConstants::kNsamps, -0.5,
                                      NSnConstants::kNsamps-0.5,
                                      200, -900, 900);
                  hd->SetBit(TH1::kCanDelete);
                  hd->Draw();
                  gorg[ch]->Draw("pc");
                  goen[ch]->Draw("pc");
                  gocp[xc]->Draw("pc");
                  gshf[ch][xc]->Draw("pc");
                  gshe[ch][xc]->Draw("pc");
               }
            }
            cdbgdt->cd();
            cdbgdt->Update();
            cdbgdt->WaitPrimitive();
            for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
               delete gorg[ch]; delete gocp[ch]; delete goen[ch];
               for (Int_t xc=0; xc<ch; ++xc) {
                  delete gshf[ch][xc];
                  delete gshe[ch][xc];
               }
            }
            delete cdbgdt;
#endif
         } else {

            Int_t npars(2);
            Double_t (*fitFunction)(const Double_t*) = 0;
            if (fitType==0) {
               fitFunction = &getShiftLL;
            } else if (fitType==5) {
               fitFunction = &getShiftChi2;
            } else {
               Fatal("bounceStudy","Unknown fit type %d",fitType);
            }
            
            mini->Clear();
            ROOT::Math::Functor f(fitFunction, npars);
            mini->SetFunction(f);
            
            if (strcmp(minner,"Genetic")==0) {
               mini->SetLimitedVariable(0, "theta",     3, 0.01,
                                        0, TMath::Pi());
               mini->SetLimitedVariable(1, "phi"  ,   5.5, 0.01,
                                        0, TMath::TwoPi());
            } else {
               //mini->SetVariable(0, "theta",             TMath::Pi(), 0.01);
               //mini->SetVariable(1, "phi"  ,   (gRandom->Rndm()-0.5), 0.01);
               mini->SetVariable(0, "theta",     3, 0.01);
               mini->SetVariable(1, "phi"  ,   5.5, 0.01);
               //mini->SetVariable(0, "theta",     3, 0.05);
               //mini->SetVariable(1, "phi"  ,   5.5, 0.05);
            }
            mini->Minimize();
            const Double_t* result = mini->X();
            tThetaPhiFit->Fill(ev, result[0], result[1], mini->MinValue());


#ifdef DEBUG_THETAPHI
            // regularize the angles
            Double_t theta = TVector2::Phi_mpi_pi(result[0]);
            Double_t phi   = result[1];
            if (theta<0) {
               theta *= -1.0;
               phi   += TMath::Pi();
            }
            phi   = TVector2::Phi_0_2pi(phi);
            Printf("theta=%g, phi=%g (%g, %g)",
                   theta*TMath::RadToDeg(),
                   phi*TMath::RadToDeg(),
               result[0], result[1]);
            TCanvas* cdbgtp = new TCanvas("cdbgtp","cdbgtp",1000,1000);
            cdbgtp->Divide(2,3);
            Float_t xxsm[NSnConstants::kNsamps];
            for (Int_t i=0; i<NSnConstants::kNsamps; ++i) {
               xxsm[i] = i;
            }
            
            TGraph* gorg[NSnConstants::kNchans];
            TGraph* gocp[NSnConstants::kNchans];
            TGraph* gshf[NSnConstants::kNchans][NSnConstants::kNchans];
            for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
               gorg[ch] = new TGraph(NSnConstants::kNsamps, xxsm,
                                     &(filtered[ch][0]));
               gocp[ch] = new TGraph(NSnConstants::kNsamps, xxsm,
                                     &(filtered[ch][0]));
               for (Int_t xc=0; xc<ch; ++xc) {
                  Double_t dtcor=0;
                  for (Int_t i=(ch-xc); i>0; --i) {
                     dtcor += dtCorrs[ch-i];
                  }
                  const TVector3& posCh = getStnPos(ch);
                  const TVector3& posXc = getStnPos(xc);
                  TVector3 norm;
                  norm.SetMagThetaPhi(1.0, result[0], result[1]);
                  //norm.SetMagThetaPhi(1.0, 2.95833, 5.497787);
                  const Double_t  disCh = -(posCh.Dot(norm));
                  const Double_t  disXc = -(posXc.Dot(norm));
                  // !!! check sign of delta(distance) and dtcor!
                  const Double_t  dt = kSmpRate * (
                     ( (disCh-disXc) * kNgTopFern / kC_m_ns )   // from m to ns
                     + dtcor );
                  Printf("dt[%d,%d]=%g (dis[%d]=%g, dis[%d]=%g)",
                         ch,xc,dt, ch,disCh,xc,disXc);
                  gshf[ch][xc] = new TGraph(NSnConstants::kNsamps);
                  for (Int_t i=0; i<NSnConstants::kNsamps; ++i) {
                     gshf[ch][xc]->SetPoint(i, xxsm[i]+dt, filtered[xc][i]);
                  }
                  gshf[ch][xc]->SetMarkerStyle(7);
                  gshf[ch][xc]->SetLineColor(kRed);
                  gshf[ch][xc]->SetMarkerColor(kRed);
               }
               gorg[ch]->SetMarkerStyle(7);
               gorg[ch]->SetLineColor(kBlack);
               gorg[ch]->SetMarkerColor(kBlack);
               gocp[ch]->SetMarkerStyle(7);
               gocp[ch]->SetLineStyle(7);
               gocp[ch]->SetLineColor(kGreen+2);
               gocp[ch]->SetMarkerColor(kGreen+2);
            }
            gStyle->SetOptStat(0);
            Int_t pp=0;
            for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
               for (Int_t xc=0; xc<ch; ++xc) {
                  cdbgtp->cd(++pp);
                  hn = Form("hd_%d_%d",ch,xc);
                  TH2F* hd = new TH2F(hn.Data(),
                                      Form("black=ch%d, red/green=ch%d;"
                                           "sample;ADC",ch,xc),
                                      NSnConstants::kNsamps, -0.5,
                                      NSnConstants::kNsamps-0.5,
                                      200, -900, 900);
                  hd->SetBit(TH1::kCanDelete);
                  hd->Draw();
                  gorg[ch]->Draw("pc");
                  gocp[xc]->Draw("pc");
                  gshf[ch][xc]->Draw("pc");
               }
            }
            cdbgtp->cd();
            cdbgtp->Update();
            cdbgtp->WaitPrimitive();
            for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
               delete gorg[ch]; delete gocp[ch];
               for (Int_t xc=0; xc<ch; ++xc) {
                  delete gshf[ch][xc];
               }
            }
            delete cdbgtp;
#endif

         }

         for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) {
            for (Int_t xc=0; xc<ch; ++xc) {
               delete gspl[ch][xc];
               delete gcor[ch][xc];
               delete gchi[ch][xc];
               delete gspc[ch][xc];
            }
         }

      }
   } // event loop

   outf->Write();

}