NCFS-Pack
A generic (astro)particle physics analysis framework
 
Loading...
Searching...
No Matches
NcAstrolab.cxx
Go to the documentation of this file.
1
31
33
187
188#include "NcAstrolab.h"
189#include "Riostream.h"
190
191ClassImp(NcAstrolab); // Class implementation to enable ROOT I/O
192
194NcAstrolab::NcAstrolab(const char* name,const char* title) : TTask(name,title),NcTimestamp()
195{
201
202 fExperiment="User";
203 fLabId=0;
204 fToffset=0;
205 fRefs=0;
206 fSigs=0;
207 fNen[0]=0;
208 fNen[1]=0;
209 fBias=0;
210 fGal=0;
211 fIndices=0;
212 fUsMeridian=0;
213 fMeridian=0;
214 fProj="none";
215 fCanvas=0;
216 fHist[0]=0;
217 fHist[1]=0;
218 fMarkers=0;
219 fMarkerSize[0]=1.5;
220 fMarkerSize[1]=1;
221 fMarkerSize[2]=1.5;
222 fMarkerSize[3]=0.3;
223 fMarkerStyle[0]=29;
224 fMarkerStyle[1]=8;
225 fMarkerStyle[2]=34;
226 fMarkerStyle[3]=8;
227 fMarkerColor[0]=kRed;
228 fMarkerColor[1]=kBlue;
229 fMarkerColor[2]=kBlack;
230 fMarkerColor[3]=kBlack;
231 fSkyMapPanel=0;
232 fTscmode=0;
233 fTscmin=0;
234 fTscmax=0;
235 fTscfunc=0;
236 fRscmode=0;
237 fDscmin=0;
238 fDscmax=0;
239 fDscfunc=0;
240 fThetascmin=0;
241 fThetascmax=0;
242 fThetascfunc=0;
243 fPhiscmin=0;
244 fPhiscmax=0;
245 fPhiscfunc=0;
246 fRan=0;
247 fMaxDt=-1;
248 fSolUpdate=0;
249
250 // Standard values (Particle Data Group 2018) for some (astro)physical parameters
251 fSpeedC=299792458;
252 fQe=1.602176565e-19;
253 fMe=0.510998928;
254 fMmu=105.6583715;
255 fMtau=1776.82;
256 fAmu=931.494061;
257 fMp=1.007276466812*fAmu;
258 fMn=1.00866491600*fAmu;
259 fMW=80.385;
260 fGammaW=2.085;
261 fMZ=91.1876;
262 fGammaZ=2.4952;
263 fAlphaEM=1./137.035999074;
264 fFermi=1.1663787e-5;
265 fPlanck=6.62606957e-34;
266 fBoltz=1.3806488e-23;
267 fNewton=6.67384e-11;
268 fGn=9.80665;
269 fAu=1.49597870700e11;
270 fPc=3.08567758149e16;
271 // Cosmological parameters from the final Planck 2018 results (arXiv:1807.06209)
272 fHubble=67.4;
273 fOmegaM=0.315;
274 fOmegaR=5.38e-5;
275 fOmegaL=0.685;
276 fOmegaB=0.0492;
277 fOmegaC=0.264;
278
279 // Some derived (astro)physical parameters c.q. conversion constants
280 fHbar=6.58211928e-22;
281 fHbarc=197.3269718;
282 fHbarc2=3.89379338e-4;
283
284 // Function to parametrize the Neutrino-Lepton kinematic opening angle
285 fNuAngle=0;
286
287 // Specifications of the data from a ROOT input Tree
288 fDataDir=0;
289 fDataFrame="undefined";
290 fDataMode="undefined";
291
292 // Identifiers of the signal and background energy profiles
293 fSigEmode="-";
294 fBkgEmode="-";
295
296 // Storage for transient burst investigations
298
299 // Initialize the default values for the burst parameters
300 SetBurstParameter("*",0);
301
302 // Load the UTC parameters
304
305 // Set the default local frame convention
306 // X-axis pointing South (=Greenwich)
307 // Y-axis pointing East
308 // Z-axis pointing towards Zenith
309 SetLocalFrame(90,0,90,90,0,0);
310
311 // First initialization of the various SkyMapPanel GUI parameters.
312 // In case SkyMapPanel() is invoked, the current Lab settings will be imported.
313 fSkyMapPanel=0;
314 fMapTS.LoadUTCparameterFiles();
315 for (Int_t i=0; i<3; i++)
316 {
317 fMapLabLBI[i]=0;
318 }
319 fMapLabU=0;
320 fMapLabE=0;
321 fMapLabLocL=0;
322 fMapLabLocB=0;
323 fMapLabLocU="deg";
324 fMapLabExpName="User";
325 fMapLabId=0;
328 fMapDate="";
329 fMapTime="";
330 fMapTimeType="-";
331 fMapDateTime="";
332 fMapLabTS=kTRUE;
333 for (Int_t i=0; i<6; i++)
334 {
335 fMapLabLframe[i]=0;
336 }
337 fMapCinfo="Lab";
338 fMapTinfo=-1;
339 fMapUinfo="deg";
340 fMapIname="";
341 fMapEa=0;
342 fMapEua="deg";
343 fMapEb=0;
344 fMapEub="deg";
345 fMapEtype=1;
346 fMapEcoord="-";
347 fMapEmode="-";
348 fMapEname="";
349 fMapDcoord="-";
350 fMapProj="-";
351 fMapDmode="-";
352 for (Int_t i=0; i<5; i++)
353 {
354 fMapDoptions[i]=kFALSE;
355 }
356 fMapNmax=-1;
357 fMapNdigs=1;
358 fMapDname="";
359 for (Int_t i=0; i<10; i++)
360 {
361 fMapSolar[i]=kFALSE;
362 }
363 fMapMerMode=0;
364 fMapMerC=0;
365 fMapMerUc="deg";
366 fMapMarkSize=1;
367 fMapMarkStyle=23;
368 fMapMarkColor=kRed;
369 fMapMarkType=0;
370}
371
373{
379
380 if (fRefs)
381 {
382 delete fRefs;
383 fRefs=0;
384 }
385 if (fSigs)
386 {
387 delete fSigs;
388 fSigs=0;
389 }
390 if (fIndices)
391 {
392 delete fIndices;
393 fIndices=0;
394 }
395 for (Int_t i=0; i<2; i++)
396 {
397 if (fHist[i])
398 {
399 delete fHist[i];
400 fHist[i]=0;
401 }
402 }
403 if (fMarkers)
404 {
405 delete fMarkers;
406 fMarkers=0;
407 }
408 if (fCanvas)
409 {
410 if (gROOT->GetListOfCanvases()->FindObject("NcAstrolab")) delete fCanvas;
411 fCanvas=0;
412 }
413 if (fTscfunc)
414 {
415 delete fTscfunc;
416 fTscfunc=0;
417 }
418 if (fDscfunc)
419 {
420 delete fDscfunc;
421 fDscfunc=0;
422 }
423 if (fThetascfunc)
424 {
425 delete fThetascfunc;
426 fThetascfunc=0;
427 }
428 if (fPhiscfunc)
429 {
430 delete fPhiscfunc;
431 fPhiscfunc=0;
432 }
433 if (fRan)
434 {
435 delete fRan;
436 fRan=0;
437 }
438
439 if (fNuAngle)
440 {
441 delete fNuAngle;
442 fNuAngle=0;
443 }
444
446 {
447 delete fBurstParameters;
449 }
450
451 // Remove the subtasks from the internal TTask list without deleting them
452 if (fTasks) fTasks->Clear();
453}
454
456{
462
465 fLabId=t.fLabId;
466 fL=t.fL;
467 Int_t size=0;
468 fRefs=0;
469 if (t.fRefs)
470 {
471 size=t.fRefs->GetSize();
472 fRefs=new TObjArray(size);
473 for (Int_t i=0; i<size; i++)
474 {
475 NcSignal* sx=(NcSignal*)t.fRefs->At(i);
476 if (sx) fRefs->AddAt(sx->Clone(),i);
477 }
478 }
479 fSigs=0;
480 if (t.fSigs)
481 {
482 size=t.fSigs->GetSize();
483 fSigs=new TObjArray(size);
484 for (Int_t i=0; i<size; i++)
485 {
486 NcSignal* sx=(NcSignal*)t.fSigs->At(i);
487 if (sx) fSigs->AddAt(sx->Clone(),i);
488 }
489 }
490 fNen[0]=t.fNen[0];
491 fNen[1]=t.fNen[1];
492 fBias=0;
493 fGal=0;
494 fIndices=0;
495 fMeridian=-999;
496 fProj="none";
497 fCanvas=0;
498 for (Int_t ih=0; ih<2; ih++)
499 {
500 fHist[ih]=0;
501 }
502 fMarkers=0;
503 for (Int_t i=0; i<4; i++)
504 {
505 fMarkerSize[i]=t.fMarkerSize[i];
506 fMarkerStyle[i]=t.fMarkerStyle[i];
507 fMarkerColor[i]=t.fMarkerColor[i];
508 }
509
510 fTscmode=0;
511 fTscmin=0;
512 fTscmax=0;
513 fTscfunc=0;
514 SetTimeScramble(t.fTscmode,t.fTscmin,t.fTscmax,t.fTscfunc);
515
516 fRscmode=0;
517 fDscmin=0;
518 fDscmax=0;
519 fDscfunc=0;
520 fThetascmin=0;
521 fThetascmax=0;
522 fThetascfunc=0;
523 fPhiscmin=0;
524 fPhiscmax=0;
525 fPhiscfunc=0;
526 SetPositionScramble(t.fRscmode,t.fDscmin,t.fDscmax,t.fDscfunc,t.fThetascmin,t.fThetascmax,t.fThetascfunc,t.fPhiscmin,t.fPhiscmax,t.fPhiscfunc);
527
528 fRan=0;
529 NcRandom* ran=t.fRan;
530 if (ran) fRan=new NcRandom(*ran);
531
532 fMaxDt=t.fMaxDt;
533
534 TF1* fx=t.fNuAngle;
535 if (fx) fNuAngle=(TF1*)fx->Clone();
536
537 NcDevice* dx=t.fBurstParameters;
538 if (dx) fBurstParameters=(NcDevice*)dx->Clone();
539}
540
541void NcAstrolab::Data(Int_t mode,TString u,Bool_t utc)
542{
564
565 TString name=GetName();
566 TString title=GetTitle();
567 printf(" *%-s::Data*",ClassName());
568 if (name!="") printf(" Name : %-s",name.Data());
569 if (title!="") printf(" Title : %-s",title.Data());
570 printf("\n");
571
572 Double_t l,b;
573 GetLabPosition(l,b,"deg");
574 printf(" Position longitude : "); PrintAngle(l,"deg",u,3);
575 printf(" latitude : "); PrintAngle(b,"deg",u,3);
576 printf(" for detector ID : %-i \n",fLabId);
577 printf(" Local user reference frame orientation w.r.t X0=South, Y0=East and Z0=Zenith : \n");
578 printf(" (Note : At the Poles (e.g. IceCube) South means the Greenwich meridian) \n");
579 TString saxes[3]={"Local X-axis","Local Y-axis","Local Z-axis"};
580 for (Int_t i=0; i<5; i+=2)
581 {
582 printf(" %-s : zenith=",saxes[i/2].Data()); PrintAngle(fAxes[i],"deg",u,3,kTRUE);
583 printf(" | phi="); PrintAngle(fAxes[i+1],"deg",u,3,kTRUE);
584 printf("\n");
585 }
586 printf(" Lab time offset w.r.t. UT : "); PrintTime(fToffset,12);
587 printf("\n");
588
589 // UT and Local time info
590 Date(mode,fToffset);
591
592 // Add the UTC and TAI related date/time information if requested
593 if (utc && mode!=4) Date(4);
594
595 if (fTscmode)
596 {
597 printf(" ------------------ Time scrambling ----------------- \n");
598 if (fTscmode<0)
599 {
600 printf(" *** Scrambling is applied only for off-source patch (background) data generation in MatchBurstData() *** \n");
601 printf(" *** The actual stored source and measurement data are not modified *** \n");
602 printf("\n");
603 }
604 if (abs(fTscmode)==1)
605 {
606 printf(" *** Each obtained time difference will be scrambled (mode %-i) *** \n",fTscmode);
607 printf(" *** The angular differences are not affected *** \n");
608 printf(" --> Tailored for scrambling entries in a specific time window without affecting \n");
609 printf(" the event selection based on angular separation w.r.t. a source. \n");
610 }
611 if (abs(fTscmode)==2)
612 {
613 if (fTscmode>0)
614 {
615 printf(" *** Each measurement is stored with a scrambled timestamp (mode %-i) *** \n",fTscmode);
616 printf(" *** The data of the sources are not modified *** \n");
617 printf(" *** Off-source (background) data : At each source matching, the measurement is given a new scrambled fake timestamp *** \n");
618 printf(" --> Tailored for blind analyses without access to the unblinded measurement data \n");
619 }
620 else
621 {
622 printf(" *** At each source matching, the measurement is given a new scrambled fake timestamp (mode %-i) *** \n",fTscmode);
623 }
624 printf(" --> Possible patterns in the distribution of sources on the sky will stay intact \n");
625 }
626 if (abs(fTscmode)==3)
627 {
628 printf(" *** At each measurement matching, the source is retrieved from the storage with a scrambled fake timestamp (mode %-i) *** \n",fTscmode);
629 printf(" *** The measurements are not affected --> Detection efficiency is unaltered *** \n");
630 printf(" --> Both time and angular differences will be scrambled \n");
631 printf(" --> Possible patterns in the distribution of sources on the sky will be washed out \n");
632 }
633 TString sx="offsets";
634 if (abs(fTscmode)==1) sx="differences";
635 printf(" Time %-s are randomly drawn from the interval [%-g,%-g] sec. \n",sx.Data(),fTscmin,fTscmax);
636 if (fTscfunc)
637 {
638 printf(" Randomising TF1 function %-s is used. \n",fTscfunc->GetName());
639 }
640 else
641 {
642 printf(" Uniform randomisation is used. \n");
643 }
644 }
645
646 if (fRscmode)
647 {
648 printf(" ------------------ Position scrambling ------------------ \n");
649 if (fRscmode<0)
650 {
651 printf(" *** Scrambling is applied only for off-source patch (background) data generation in MatchBurstData() *** \n");
652 printf(" *** The actual stored source and measurement data are not modified *** \n");
653 }
654 else
655 {
656 printf(" *** The data of the sources and the measurement timestamps are not modified *** \n");
657 }
658 printf("\n");
659
660 if (abs(fRscmode)==1)
661 {
662 printf(" *** Each obtained angular difference will be scrambled (mode %-i) *** \n",fRscmode);
663 printf(" *** The time differences are not affected *** \n");
664 printf(" ---> Tailored for scrambling entries within a specific angular range w.r.t. a source,");
665 printf(" without affecting the event selection based on the time difference w.r.t. a transient source. \n");
666 printf(" Angular differences are randomly drawn from the interval [%-g,%-g] degrees. \n",fDscmin,fDscmax);
667 if (fDscfunc)
668 {
669 printf(" Randomising TF1 function %-s is used. \n",fDscfunc->GetName());
670 }
671 else
672 {
673 printf(" Homogeneous solid angle randomisation is used. \n");
674 }
675 }
676
677 if (fRscmode==2)
678 {
679 printf(" *** Each measurement is stored with a scrambled fake local position (mode %-i) *** \n",fRscmode);
680 printf(" *** Off-source (background) data : At each source matching, the measurement is given a new scrambled fake local position *** \n");
681 printf(" --> Tailored for blind analyses without access to the unblinded measurement data \n");
682 }
683
684 if (abs(fRscmode)==3 || fRscmode==-2)
685 {
686 printf(" *** At each source matching, the measurement is given a new scrambled fake local position (mode %-i) *** \n",fRscmode);
687 }
688
689 if (abs(fRscmode)>1)
690 {
691 printf(" The local coordinates (r,theta,phi) of the measurement are modified to (r+dr,theta+dtheta,phi+dphi) with : \n");
692
693 printf(" dr is randomly drawn from the interval [%-g,%-g] \n",fDscmin,fDscmax);
694 if (fDscfunc)
695 {
696 printf(" Randomising TF1 function %-s is used. \n",fDscfunc->GetName());
697 }
698 else
699 {
700 printf(" Uniform randomisation is used. \n");
701 }
702
703 printf(" dtheta is randomly drawn from the interval [%-g,%-g] degrees. \n",fThetascmin,fThetascmax);
704 if (fThetascfunc)
705 {
706 printf(" Randomising TF1 function %-s is used. \n",fThetascfunc->GetName());
707 }
708 else
709 {
710 printf(" Uniform cos(theta) randomisation is used. \n");
711 }
712
713 printf(" dphi is randomly drawn from the interval [%-g,%-g] degrees. \n",fPhiscmin,fPhiscmax);
714 if (fPhiscfunc)
715 {
716 printf(" Randomising TF1 function %-s is used. \n",fPhiscfunc->GetName());
717 }
718 else
719 {
720 printf(" Uniform phi randomisation is used. \n");
721 }
722 }
723 }
724
725 printf(" ------------------ \n");
726 if (fRan)
727 {
728 Int_t iseed,cnt1,cnt2;
729 GetRandomiser(iseed,cnt1,cnt2);
730 cout << " *** Current settings of the internal NcRandom randomiser : iseed=" << iseed << " cnt1=" << cnt1 << " cnt2=" << cnt2 << endl;
731 }
732 else
733 {
734 cout << " *** The internal NcRandom randomiser is currently not intialised ***" << endl;
735 cout << " Automatic initialisation will be performed with the actual timestamp at the first random number request." << endl;
736 cout << " This will ensure different random sequences for different NcAstrolab instances." << endl;
737 cout << " To obtain reproducible scrambled results, please invoke SetRandomiser() before the first SetSignal() invokation." << endl;
738 }
739 printf(" ------------------ \n");
740}
741
743{
764
765 fLabPos.SetPosition(p);
766
767 // Determine local time offset in fractional hours w.r.t. UT.
768 Double_t vec[3];
769 p.GetVector(vec,"sph","deg");
770 Double_t l=vec[2];
771 fToffset=l/15.;
772}
773
774void NcAstrolab::SetLabPosition(Double_t l,Double_t b,TString u)
775{
808
809 Double_t r=1,theta=0,phi=0;
810
811 l=ConvertAngle(l,u,"deg");
812 b=ConvertAngle(b,u,"deg");
813
814 Double_t offset=90.;
815
816 theta=offset-b;
817 phi=l;
818
819 Double_t p[3]={r,theta,phi};
820 fLabPos.SetPosition(p,"sph","deg");
821
822 // Local time offset in fractional hours w.r.t. UT.
823 fToffset=l/15.;
824}
825
826void NcAstrolab::SetExperiment(TString name,Int_t id)
827{
866
867 fExperiment="User";
868 fLabId=0;
869
870 Double_t l=0; // Longitude
871 Double_t b=0; // Lattitude
872
873 if (name=="User")
874 {
875 SetNameTitle("User","Virtual Lab for general use");
876 SetLabPosition(0,90,"deg"); // North Pole
877 // Right handed local grid frame has X-South (to Greenwich), Y-East and Z-Zenith
878 // which is the same as the Master Reference Frame (MRF)
879 SetLocalFrame(90,0,90,90,0,0);
880 fExperiment=name;
881 fLabId=id;
882 return;
883 }
884
885 if (name=="Greenwich")
886 {
887 // Exact location : 51d 28' 36.6672" (N) and 0d 0' 1.8000" (W)
888 SetNameTitle("Greenwich","The Royal Observatory in the UK");
889 l=-0.000500;
890 b=51.476852;
891 SetLabPosition(l,b,"deg"); // South Pole
892 // Right handed Greenwich local grid frame has X-South, Y-East and Z-Zenith
893 // which is the same as the Master Reference Frame (MRF)
894 SetLocalFrame(90,0,90,90,0,0);
895 fExperiment=name;
896 return;
897 }
898
899 if (name=="Amanda")
900 {
901 SetNameTitle("Amanda","Antarctic Muon And Neutrino Detector Array");
902 SetLabPosition(0,-90,"deg"); // South Pole
903 // Right handed Amanda local grid frame has Y-North (to Greenwich), X-East and Z-Zenith
904 SetLocalFrame(90,90,90,180,0,0);
905 fExperiment=name;
906 return;
907 }
908
909 if (name=="IceCube")
910 {
911 // Exact location : 89d 59' 23.977" (S) and 63d 37' 21.432" (W)
912 SetNameTitle("IceCube","The South Pole Neutrino Observatory");
913 l=-63.453056;
914 b=-89.99;
915 SetLabPosition(l,b,"deg"); // South Pole
916 // Right handed IceCube local grid frame has Y-North (to Greenwich), X-East and Z-Zenith
917 SetLocalFrame(90,90.+l,90,180.+l,0,0);
918 fExperiment=name;
919 return;
920 }
921
922 if (name=="WSRT")
923 {
924 SetNameTitle("WSRT","The Westerbork Synthesis Radio Telescope");
925 SetLabPosition(63612.74,525454.33,"dms");
926 // Right handed local grid frame has X-South, Y-East and Z-Zenith
927 // which is the same as the Master Reference Frame (MRF)
928 SetLocalFrame(90,0,90,90,0,0);
929 fExperiment=name;
930 return;
931 }
932
933 if (name=="Astron")
934 {
935 SetNameTitle("Astron","The Netherlands Institute for Radio Astronomy");
936 SetLabPosition(62346.23,524843.99,"dms");
937 // Right handed local grid frame has X-South, Y-East and Z-Zenith
938 // which is the same as the Master Reference Frame (MRF)
939 SetLocalFrame(90,0,90,90,0,0);
940 fExperiment=name;
941 return;
942 }
943
944 if (name=="ARA")
945 {
946 SetNameTitle("ARA","The Askaryan Radio Array at the South Pole");
947 SetLabPosition(0,-90,"deg"); // South Pole
948 // Right handed ARA local grid frame has Y-North (to Greenwich), X-East and Z-Zenith
949 SetLocalFrame(90,90,90,180,0,0);
950 fExperiment=name;
951 return;
952 }
953
954 if (name=="RNO-G")
955 {
956 SetNameTitle("RNO-G","The Greenland Radio Neutrino Observatory at Summit Station");
957 // Use the location of the Big House as global location
958 l=-38.4604;
959 b=72.57889;
960
961 // The locations of the various stations
962 Int_t ids[35]={11,12,13,14,15,16,17,21,22,23,24,25,26,27,33,34,35,36,37,44,45,46,47,54,55,56,57,64,65,66,67,74,75,76,77};
963 Float_t ls[35]={-38.5023,-38.4962,-38.4901,-38.4841,-38.4780,-38.4719,-38.4657,-38.4660,-38.4599,-38.4538,-38.4477,-38.4416,-38.4355,-38.4293, /*last is 27*/
964 -38.4175,-38.4114,-38.4053,-38.3991,-38.3930,-38.3751,-38.3689,-38.3627,-38.3566,-38.3388,-38.3326,-38.3264,-38.3202,-38.3025, /*last is 64*/
965 -38.2963,-38.2900,-38.2838,-38.2662,-38.2599,-38.2537,-38.2474};
966 Float_t bs[35]={72.58923,72.60009,72.61095,72.62181,72.63267,72.64353,72.65439,72.58741,72.59827,72.60912,72.61998,72.63084,72.64170,72.65256, /*last is 27*/
967 72.60729,72.61815,72.62901,72.63987,72.65073,72.61631,72.62717,72.63803,72.64889,72.61447,72.62533,72.63618,72.64704,72.61262, /*last is 64*/
968 72.62347,72.63433,72.64518,72.61076,72.62161,72.63247,72.64332};
969
970 // Select a specific station, if requested
971 if (id)
972 {
973 for (Int_t i=0; i<35; i++)
974 {
975 if (id==ids[i])
976 {
977 l=ls[i];
978 b=bs[i];
979 fLabId=id;
980 break;
981 }
982 }
983 }
984
985 // Set the selected location
986 SetLabPosition(l,b,"deg"); // Summit Station
987 // Right handed RNO-G local grid frame has Y-North, X-East and Z-Zenith
988 SetLocalFrame(90,90,90,180,0,0);
989 fExperiment=name;
990 return;
991 }
992
993 if (name=="ARCA")
994 {
995 SetNameTitle("ARCA","The KM3NeT/ARCA Neutrino detector near Sicily");
996 SetLabPosition(155842.25,361748.34,"dms");
997 // Right handed ARCA local grid frame has Y-North, X-East and Z-Zenith
998 SetLocalFrame(90,90,90,180,0,0);
999 fExperiment=name;
1000 return;
1001 }
1002
1003 cout << " *" << ClassName() << "::SetExperiment* Unsupported experiment name : " << name.Data() << endl;
1004 printf(" Experiment is set to %-s with detector identifier %-i \n",fExperiment.Data(),fLabId);
1005}
1006
1008{
1018
1019 fToffset=dt;
1020}
1021
1023{
1032
1033 return fLabPos;
1034}
1035
1036void NcAstrolab::GetLabPosition(Double_t& l,Double_t& b,TString u) const
1037{
1053
1054 Double_t pi=acos(-1.);
1055
1056 Double_t offset=90.;
1057 if (u=="rad") offset=pi/2.;
1058
1059 Double_t p[3];
1060 fLabPos.GetPosition(p,"sph",u);
1061 b=offset-p[1];
1062 l=p[2];
1063}
1064
1066{
1072
1073 return fExperiment;
1074}
1075
1077{
1083
1084 return fLabId;
1085}
1086
1088{
1096
1097 return fToffset;
1098}
1099
1100void NcAstrolab::SetRandomiser(Int_t iseed,Int_t cnt1,Int_t cnt2,NcTimestamp* ts)
1101{
1145
1146 if (!ts) ts=(NcTimestamp*)this;
1147
1148 if (fRan) delete fRan;
1149
1150 fRan=new NcRandom(iseed,cnt1,cnt2,ts);
1151}
1152
1153NcRandom* NcAstrolab::GetRandomiser(Int_t& iseed,Int_t& cnt1,Int_t& cnt2) const
1154{
1164
1165 iseed=-1;
1166 cnt1=-1;
1167 cnt2=-1;
1168
1169 if (!fRan) return 0;
1170
1171 iseed=fRan->GetSeed();
1172 cnt1=fRan->GetCnt1();
1173 cnt2=fRan->GetCnt2();
1174
1175 return fRan;
1176}
1177
1178void NcAstrolab::SetMaxDt(Double_t s)
1179{
1191
1192 fMaxDt=s;
1193}
1194
1195Double_t NcAstrolab::GetMaxDt() const
1196{
1206
1207 return fMaxDt;
1208}
1209
1211{
1220
1221 Double_t h=GetLT(fToffset);
1222 return h;
1223}
1224
1226{
1238
1239 Double_t h=GetLMST(fToffset);
1240 return h;
1241}
1242
1244{
1256
1257 Double_t h=GetLAST(fToffset);
1258 return h;
1259}
1260
1261void NcAstrolab::PrintAngle(Double_t a,TString in,TString out,Int_t ndig,Bool_t align) const
1262{
1298
1299 Double_t b=ConvertAngle(a,in,out);
1300
1301 if (out=="deg" || out=="rad")
1302 {
1303 if (align)
1304 {
1305 printf("%*.*f %-s",5+ndig,ndig,b,out.Data());
1306 }
1307 else
1308 {
1309 printf("%-.*f %-s",ndig,b,out.Data());
1310 }
1311 return;
1312 }
1313
1314 Double_t epsilon=1.e-12; // Accuracy in (arc)seconds
1315 Int_t word=0,ddd=0,hh=0,mm=0,ss=0;
1316 Double_t s;
1317
1318 if (out=="dms")
1319 {
1320 word=Int_t(b);
1321 word=abs(word);
1322 ddd=word/10000;
1323 word=word%10000;
1324 mm=word/100;
1325 ss=word%100;
1326 s=fabs(b)-Double_t(ddd*10000+mm*100+ss);
1327 if (s>(1.-epsilon))
1328 {
1329 s=0.;
1330 ss++;
1331 }
1332 while (ss>=60)
1333 {
1334 ss-=60;
1335 mm++;
1336 }
1337 while (mm>=60)
1338 {
1339 mm-=60;
1340 ddd++;
1341 }
1342 while (ddd>=360)
1343 {
1344 ddd-=360;
1345 }
1346 if (b<0) ddd=-ddd;
1347 s+=double(ss);
1348 if (align)
1349 {
1350 if (!ddd && b<0)
1351 {
1352 printf(" -0d %02i' %0*.*f\"",mm,3+ndig,ndig,s);
1353 }
1354 else
1355 {
1356 printf("%4id %02i' %0*.*f\"",ddd,mm,3+ndig,ndig,s);
1357 }
1358 }
1359 else
1360 {
1361 if (!ddd && b<0)
1362 {
1363 printf("-0d %-i' %-.*f\"",mm,ndig,s);
1364 }
1365 else
1366 {
1367 printf("%-id %-i' %-.*f\"",ddd,mm,ndig,s);
1368 }
1369 }
1370 return;
1371 }
1372
1373 if (out=="hms")
1374 {
1375 word=Int_t(b);
1376 word=abs(word);
1377 hh=word/10000;
1378 word=word%10000;
1379 mm=word/100;
1380 ss=word%100;
1381 s=fabs(b)-Double_t(hh*10000+mm*100+ss);
1382 if (s>(1.-epsilon))
1383 {
1384 s=0.;
1385 ss++;
1386 }
1387 while (ss>=60)
1388 {
1389 ss-=60;
1390 mm++;
1391 }
1392 while (mm>=60)
1393 {
1394 mm-=60;
1395 hh++;
1396 }
1397 while (hh>=24)
1398 {
1399 hh-=24;
1400 }
1401 if (b<0) hh=-hh;
1402 s+=double(ss);
1403 if (align)
1404 {
1405 if (!hh && b<0)
1406 {
1407 printf(" -0h %02im %0*.*fs",mm,3+ndig,ndig,s);
1408 }
1409 else
1410 {
1411 printf("%3ih %02im %0*.*fs",hh,mm,3+ndig,ndig,s);
1412 }
1413 }
1414 else
1415 {
1416 if (!hh && b<0)
1417 {
1418 printf("-0h %-im %-.*fs",mm,ndig,s);
1419 }
1420 else
1421 {
1422 printf("%-ih %-im %-.*fs",hh,mm,ndig,s);
1423 }
1424 }
1425 return;
1426 }
1427}
1428
1429NcSignal* NcAstrolab::SetSignal(Nc3Vector* r,TString frame,TString mode,NcTimestamp* ts,Int_t jref,TString name,Int_t type)
1430{
1502
1503 // Cope with the (obsolete) jref=0 specification
1504 if (!jref)
1505 {
1506 type=1;
1507 jref=1;
1508 delete fSigs;
1509 fSigs=0;
1510 }
1511
1512 if (!r) return 0;
1513
1514 if (!r->HasVector()) return 0;
1515
1516 if (frame!="equ" && frame!="gal" && frame!="ecl" && frame!="hor" && frame!="icr" && frame!="loc") return 0;
1517
1518 if (frame=="equ" && mode!="M" && mode!="m" && mode!="T" && mode!="t" && mode!="B" && mode!="b" && mode!="J" && mode!="j") return 0;
1519
1520 NcSignal* sx=0;
1521
1522 if (!ts) ts=(NcTimestamp*)this;
1523
1524 // Make a local copy of the timestamp to make sure that the newly stored
1525 // signal will never contain the Tree with the UTCparameter data.
1526 NcTimestamp ts2;
1527 Int_t mjd=0;
1528 Int_t isec=0;
1529 Int_t ins=0;
1530 Int_t ips=0;
1531 ts->GetMJD(mjd,isec,ins);
1532 ips=ts->GetPs();
1533 ts2.SetMJD(mjd,isec,ins,ips);
1534
1535 Double_t vec[3];
1536 vec[0]=r->GetX(1,"sph","rad");
1537 vec[1]=r->GetX(2,"sph","rad");
1538 vec[2]=r->GetX(3,"sph","rad");
1539 Nc3Vector q;
1540 q.SetVector(vec,"sph","rad");
1541
1542 // Recursive invokation in case of local coordinates
1543 if (frame=="loc")
1544 {
1545 // Convert to horizontal coordinates
1546 q=q.GetUnprimed(&fL);
1547
1548 // Store the signal
1549 sx=SetSignal(&q,"hor",mode,&ts2,jref,name,type);
1550 return sx;
1551 }
1552
1553 // If needed, initialise the randomiser with a "date/time driven" seed
1554 // using the timestamp of the moment of this invokation of the member function.
1555 // This will ensure different random sequences if the user repeats analyses
1556 // with identical measurements and reference signals without explicit initialisation
1557 // of the randomiser by the user at the start of the analysis.
1558 if (!fRan && type && (fTscmode==2 || fRscmode==2)) fRan=new NcRandom(-1);
1559
1560 // Local timestamp copy to allow time scrambling
1561 NcTimestamp tx(ts2);
1562
1563 // Perform time scrambling (measurements only) if requested
1564 if (type && fTscmode==2)
1565 {
1566 Double_t dt=0;
1567
1568 // Allow for specific offset studies
1569 if (fTscmin==fTscmax) dt=fTscmin;
1570
1571 // Go for randomly scrambled values
1572 if (fTscfunc)
1573 {
1574 if (fTscmax>fTscmin)
1575 {
1576 dt=fTscfunc->GetRandom(fTscmin,fTscmax);
1577 }
1578 }
1579 else
1580 {
1581 if (fTscmax>fTscmin) dt=fRan->Uniform(fTscmin,fTscmax);
1582 }
1583 tx.AddSec(dt);
1584 }
1585
1586 // Construct the corresponding ICRS position vector to be stored
1587 if (frame=="equ")
1588 {
1589 // Convert to "mean" values at specified epoch
1590 if (mode=="T" || mode=="t")
1591 {
1592 SetNmatrix(&tx);
1593 q=q.GetUnprimed(&fN);
1594 }
1595
1596 // Convert to "mean" values at J2000
1597 if (mode=="T" || mode=="t" || mode=="M" || mode=="m")
1598 {
1599 SetPmatrix(&tx);
1600 }
1601 else
1602 {
1603 NcTimestamp te;
1604 if (mode=="B" || mode=="b") te.SetEpoch(1950,"B");
1605 if (mode=="J" || mode=="j") te.SetEpoch(2000,"J");
1606 SetPmatrix(&te);
1607 }
1608 q=q.GetUnprimed(&fP);
1609
1610 // Convert to ICRS values
1611 if (!fBias) SetBmatrix();
1612 q=q.GetUnprimed(&fB);
1613 }
1614
1615 if (frame=="gal")
1616 {
1617 // Convert to J2000 equatorial mean coordinates
1618 if (fGal != 2) SetGmatrix("J");
1619 q=q.GetUnprimed(&fG);
1620
1621 // Convert to ICRS values
1622 if (!fBias) SetBmatrix();
1623 q=q.GetUnprimed(&fB);
1624 }
1625
1626 if (frame=="ecl")
1627 {
1628 // Convert to mean equatorial values at specified epoch
1629 SetEmatrix(&tx);
1630 q=q.GetUnprimed(&fE);
1631
1632 // Convert to "mean" values at J2000
1633 SetPmatrix(&tx);
1634 q=q.GetUnprimed(&fP);
1635
1636 // Convert to ICRS values
1637 if (!fBias) SetBmatrix();
1638 q=q.GetUnprimed(&fB);
1639 }
1640
1641 if (frame=="hor")
1642 {
1643 // Convert to "true" equatorial values at the specified timestamp
1644 SetHmatrix(&tx);
1645 q=q.GetUnprimed(&fH);
1646
1647 // Convert to "mean" values at specified timestamp
1648 SetNmatrix(&tx);
1649 q=q.GetUnprimed(&fN);
1650
1651 // Convert to "mean" values at J2000
1652 SetPmatrix(&tx);
1653 q=q.GetUnprimed(&fP);
1654
1655 // Convert to ICRS values
1656 if (!fBias) SetBmatrix();
1657 q=q.GetUnprimed(&fB);
1658 }
1659
1660 // Store the signal in ICRS coordinates
1661 Int_t size=0;
1662 Int_t jmax=0;
1663 Int_t jlast=0;
1664 if (type) // Storage of a measurement
1665 {
1666 NcSignal* sxsig=0;
1667 if (!fSigs)
1668 {
1669 fSigs=new TObjArray();
1670 fSigs->SetOwner();
1671 }
1672 // Expand array size if needed
1673 size=fSigs->GetSize();
1674 jmax=size-1;
1675 jlast=fSigs->GetLast();
1676 if (jref>0)
1677 {
1678 if (jref>size) fSigs->Expand(jref);
1679 }
1680 else
1681 {
1682 if (jlast==jmax) fSigs->Expand(size+1);
1683 }
1684 sxsig=GetSignal(jref,type);
1685 if (!sxsig)
1686 {
1687 sxsig=new NcSignal();
1688 }
1689 else
1690 {
1691 sxsig->Reset(1);
1692 }
1693 if (name=="") // Generate a corresponding measurement name
1694 {
1695 fNen[1]++;
1696 name="Meas";
1697 name+=fNen[1];
1698 name+="#";
1699 }
1700 sxsig->SetName(name);
1701 sxsig->SetTitle("Observed event in ICRS coordinates");
1702 sxsig->SetTimestamp(tx);
1703 sxsig->SetPosition(q);
1704 if (jref<0)
1705 {
1706 fSigs->Add(sxsig);
1707 }
1708 else
1709 {
1710 fSigs->AddAt(sxsig,jref-1);
1711 }
1712 sx=sxsig;
1713 }
1714 else // Storage of a reference signal
1715 {
1716 NcSignal* sxref=0;
1717 if (!fRefs)
1718 {
1719 fRefs=new TObjArray();
1720 fRefs->SetOwner();
1721 }
1722 // Expand array size if needed
1723 size=fRefs->GetSize();
1724 jmax=size-1;
1725 jlast=fRefs->GetLast();
1726 if (jref>0)
1727 {
1728 if (jref>size) fRefs->Expand(jref);
1729 }
1730 else
1731 {
1732 if (jlast==jmax) fRefs->Expand(size+1);
1733 }
1734 sxref=GetSignal(jref,type);
1735 if (!sxref)
1736 {
1737 sxref=new NcSignal();
1738 }
1739 else
1740 {
1741 sxref->Reset(1);
1742 }
1743 if (name=="") // Generate a corresponding reference name
1744 {
1745 fNen[0]++;
1746 name="Ref";
1747 name+=fNen[0];
1748 name+="#";
1749 }
1750 sxref->SetName(name);
1751 sxref->SetTitle("Reference event in ICRS coordinates");
1752 sxref->SetTimestamp(tx);
1753 sxref->SetPosition(q);
1754 if (jref<0)
1755 {
1756 fRefs->Add(sxref);
1757 }
1758 else
1759 {
1760 fRefs->AddAt(sxref,jref-1);
1761 }
1762 sx=sxref;
1763 }
1764
1765 if (fRscmode !=2 || !type) return sx;
1766
1768 // Perform position scrambling (measurements only) if requested //
1770
1771 // Get the measurement in local coordinates
1772 Int_t index=fSigs->IndexOf(sx);
1773 index++; // First storage is at index=1 and not index=0
1774 GetSignal(q,"loc",mode,&tx,index,type);
1775
1776 q.GetVector(vec,"sph","deg");
1777
1778 Double_t dd=0;
1779 Double_t dtheta=0;
1780 Double_t dphi=0;
1781
1782 // Allow specific offset studies
1783 if (fDscmin==fDscmax) dd=fDscmin;
1784 if (fThetascmin==fThetascmax) dtheta=fThetascmin;
1785 if (fPhiscmin==fPhiscmax) dphi=fPhiscmin;
1786
1787 // Go for randomly scrambled values
1788 if (fDscfunc)
1789 {
1790 if (fDscmax>fDscmin)
1791 {
1792 dd=fDscfunc->GetRandom(fDscmin,fDscmax);
1793 }
1794 }
1795 else
1796 {
1797 if (fDscmax>fDscmin) dd=fRan->Uniform(fDscmin,fDscmax);
1798 }
1799
1800 if (fThetascfunc)
1801 {
1803 {
1804 dtheta=fThetascfunc->GetRandom(fThetascmin,fThetascmax);
1805 }
1806 }
1807 else if (fThetascmax>fThetascmin)
1808 {
1809 Double_t pi=acos(-1.);
1810 Float_t cosmin=cos(fThetascmin*pi/180.);
1811 Float_t cosmax=cos(fThetascmax*pi/180.);
1812 if (cosmin>cosmax)
1813 {
1814 Float_t temp=cosmin;
1815 cosmin=cosmax;
1816 cosmax=temp;
1817 }
1818 Double_t cosang=fRan->Uniform(cosmin,cosmax);
1819 dtheta=acos(cosang)*180./pi;
1820 }
1821
1822 if (fPhiscfunc)
1823 {
1824 if (fPhiscmax>fPhiscmin)
1825 {
1826 dphi=fPhiscfunc->GetRandom(fPhiscmin,fPhiscmax);
1827 }
1828 }
1829 else
1830 {
1831 if (fPhiscmax>fPhiscmin) dphi=fRan->Uniform(fPhiscmin,fPhiscmax);
1832 }
1833
1834 vec[0]+=dd;
1835 if (vec[0]<=0) vec[0]=1e-20; // Keep a physical situation
1836 vec[1]+=dtheta;
1837 vec[2]+=dphi;
1838 q.SetVector(vec,"sph","deg");
1839
1841 // Construct the corresponding ICRS position vector to be stored //
1843
1844 // Convert to horizontal coordinates
1845 q=q.GetUnprimed(&fL);
1846
1847 // Convert to "true" equatorial values at the specified timestamp
1848 SetHmatrix(&tx);
1849 q=q.GetUnprimed(&fH);
1850
1851 // Convert to "mean" values at specified timestamp
1852 SetNmatrix(&tx);
1853 q=q.GetUnprimed(&fN);
1854
1855 // Convert to "mean" values at J2000
1856 SetPmatrix(&tx);
1857 q=q.GetUnprimed(&fP);
1858
1859 // Convert to ICRS values
1860 if (!fBias) SetBmatrix();
1861 q=q.GetUnprimed(&fB);
1862
1863 // Store the measurement position
1864 sx->SetPosition(q);
1865
1866 return sx;
1867}
1868
1869Int_t NcAstrolab::SetSolarSystem(TString name,NcTimestamp* ts,Int_t type)
1870{
1896
1897 // Only geocentric positions are allowed
1898 if (name.Contains("*")) return 0;
1899
1900 if (!ts) ts=(NcTimestamp*)this;
1901
1902 Double_t lx=0; // Geocentric ecliptic longitude of the object in degrees
1903 Double_t bx=0; // Geocentric ecliptic latitude of the object in degrees
1904 Double_t rx=0; // Distance (AU for planets, km for the Moon) between the object and the Earth.
1905
1906 Int_t set=0; // Flag to indicate that a location has been set
1907
1908 ts->Almanac(0,0,0,0,name,&lx,&bx,&rx);
1909
1910 if (rx>0) set=1;
1911
1912 // Replace c.q. store the object data as a reference or measured signal according to "type".
1913 // In case the object wasn't stored yet, jref=-1 and the object will be
1914 // added to the list of stored signals of "type".
1915 Int_t jref=GetSignalIndex(name,type);
1916 if (set && jref) SetSignal(rx,lx,"deg",bx,"deg","ecl",ts,jref,"M",name,type);
1917
1918 return set;
1919}
1920
1921NcSignal* NcAstrolab::SetSignal(Double_t d,Double_t a,TString au,Double_t b,TString bu,TString frame,NcTimestamp* ts,Int_t jref,TString mode,TString name,Int_t type)
1922{
2001
2002 // Assure physical value for the norm of the location vector
2003 if (d<=0) d=1;
2004
2005 // Convert angular coordinates to fractional degrees.
2006 a=ConvertAngle(a,au,"deg");
2007 b=ConvertAngle(b,bu,"deg");
2008
2009 Nc3Vector r;
2010 Double_t vec[3]={0,0,0};
2011 vec[0]=d;
2012
2013 // Equatorial coordinates
2014 if (frame=="equ")
2015 {
2016 if (mode!="M" && mode!="m" && mode!="T" && mode!="t" && mode!="B" && mode!="b" && mode!="J" && mode!="j") return 0;
2017 vec[1]=90.-b;
2018 vec[2]=a;
2019 }
2020
2021 // Galactic coordinates
2022 if (frame=="gal")
2023 {
2024 vec[1]=90.-b;
2025 vec[2]=a;
2026 }
2027
2028 // Geocentric ecliptic coordinates
2029 if (frame=="ecl")
2030 {
2031 vec[1]=90.-b;
2032 vec[2]=a;
2033 }
2034
2035 // Horizontal coordinates
2036 if (frame=="hor")
2037 {
2038 vec[1]=b;
2039 vec[2]=180.-a;
2040 }
2041
2042 // ICRS coordinates
2043 if (frame=="icr")
2044 {
2045 vec[1]=90.-b;
2046 vec[2]=a;
2047 }
2048
2049 // Local coordinates
2050 if (frame=="loc" || frame=="pdir")
2051 {
2052 vec[1]=a;
2053 vec[2]=b;
2054 }
2055
2056 if (!ts) ts=(NcTimestamp*)this;
2057
2058 r.SetVector(vec,"sph","deg");
2059
2060 // Revert momentum direction in order to get the source direction
2061 if (frame=="pdir")
2062 {
2063 r*=-1.;
2064 frame="loc";
2065 }
2066
2067 NcSignal* sx=SetSignal(&r,frame,mode,ts,jref,name,type);
2068 return sx;
2069}
2070
2071NcSignal* NcAstrolab::SetSignal(Double_t d,Double_t a,TString au,Double_t b,TString bu,TString frame,TString s,Double_t e,Int_t jref,TString mode,TString name,Int_t type)
2072{
2154
2155 NcTimestamp tx;
2156 tx.SetEpoch(e,s);
2157
2158 NcSignal* sx=SetSignal(d,a,au,b,bu,frame,&tx,jref,mode,name,type);
2159 return sx;
2160}
2161
2162Int_t NcAstrolab::SetSourceAttributes(NcSignal* s,Double_t sigmapos,TString u,Double_t z,Double_t T90)
2163{
2190
2191 if (!s) return 0;
2192
2193 Int_t n=3;
2194
2195 if (sigmapos<0)
2196 {
2197 sigmapos=-999;
2198 n--;
2199 }
2200 if (z<0)
2201 {
2202 z=-999;
2203 n--;
2204 }
2205 if (T90<0)
2206 {
2207 T90=-999;
2208 n--;
2209 }
2210
2211 // Convert the position uncertainty into degrees
2212 Double_t sigma=ConvertAngle(sigmapos,u,"deg");
2213
2214 s->AddNamedSlot("csigma");
2215 s->AddNamedSlot("z");
2216 s->AddNamedSlot("T90");
2217 s->SetSignal(sigma,"csigma");
2218 s->SetSignal(z,"z");
2219 s->SetSignal(T90,"T90");
2220
2221 return n;
2222}
2223
2224Double_t NcAstrolab::GetSourceAttributes(NcSignal* s,Float_t* z,Float_t* T90)
2225{
2244
2245 if (!s) return -999;
2246
2247 Double_t sigma=s->GetSignal("csigma");
2248 if (z) *z=s->GetSignal("z");
2249 if (T90) *T90=s->GetSignal("T90");
2250
2251 return sigma;
2252}
2253
2254Int_t NcAstrolab::GetNRefSignals(Int_t mode) const
2255{
2281
2282 Int_t n=GetNsignals(0,mode);
2283 return n;
2284}
2285
2286Int_t NcAstrolab::GetNsignals(Int_t type,Int_t mode) const
2287{
2311
2312 TObjArray* arr=fRefs;
2313 if (type) arr=fSigs;
2314
2315 if (!arr) return 0;
2316
2317 Int_t n=0;
2318 if (!mode)
2319 {
2320 n=arr->GetEntries();
2321 }
2322 else
2323 {
2324 n=arr->GetSize();
2325 }
2326 return n;
2327}
2328
2329NcSignal* NcAstrolab::GetSignal(Nc3Vector& r,TString frame,TString mode,NcTimestamp* ts,Int_t jref,Int_t type)
2330{
2389
2390 r.SetZero();
2391
2392 if (frame!="equ" && frame!="gal" && frame!="ecl" && frame!="hor" && frame!="icr" && frame!="loc") return 0;
2393
2394 if (frame=="equ" && mode!="M" && mode!="m" && mode!="T" && mode!="t" && mode!="B" && mode!="b" && mode!="J" && mode!="j") return 0;
2395
2396 // For backward compatibility
2397 if (!jref)
2398 {
2399 jref=1;
2400 type=1;
2401 }
2402
2403 NcSignal* sx=GetSignal(jref,type);
2404
2405 if (!sx) return 0;
2406
2407 if (!ts) ts=(NcTimestamp*)this;
2408
2409 // Check on maximum time difference
2410 if (fMaxDt>0)
2411 {
2412 NcTimestamp* tx=sx->GetTimestamp();
2413 if (!tx) return 0;
2414 Double_t dt=tx->GetDifference(ts,"s",1);
2415 if (fabs(dt)>fMaxDt) return 0;
2416 }
2417
2418 // Update coordinates for Solar system objects
2419 TString name=sx->GetName();
2420 SetSolarSystem(name,ts,type);
2421
2422 Double_t vec[3];
2423 sx->GetPosition(vec,"sph","rad");
2424 Nc3Vector q;
2425 q.SetVector(vec,"sph","rad");
2426
2427 if (frame=="icr")
2428 {
2429 r.Load(q);
2430 return sx;
2431 }
2432
2433 // Convert from ICRS to equatorial J2000 coordinates
2434 if (!fBias) SetBmatrix();
2435 q=q.GetPrimed(&fB);
2436
2437 if (frame=="equ" && mode!="J" && mode!="j")
2438 {
2439 // Precess to specified timestamp
2440 NcTimestamp ts1;
2441 ts1.SetEpoch(2000,"J");
2442 if (mode!="B" && mode!="b")
2443 {
2444 Precess(q,&ts1,ts);
2445 }
2446 else
2447 {
2448 NcTimestamp ts2;
2449 ts2.SetEpoch(1950,"B");
2450 Precess(q,&ts1,&ts2);
2451 }
2452
2453 // Nutation correction if requested
2454 if (mode=="T" || mode=="t") Nutate(q,ts);
2455 }
2456
2457 if (frame=="gal")
2458 {
2459 // Convert from equatorial J2000 to galactic
2460 if (fGal != 2) SetGmatrix("J");
2461 q=q.GetPrimed(&fG);
2462 }
2463
2464 if (frame=="ecl")
2465 {
2466 // Precess to specified timestamp
2467 NcTimestamp ts1;
2468 ts1.SetEpoch(2000,"J");
2469 Precess(q,&ts1,ts);
2470
2471 // Convert from equatorial to ecliptic coordinates
2472 SetEmatrix(ts);
2473 q=q.GetPrimed(&fE);
2474 }
2475
2476 if (frame=="hor")
2477 {
2478 // Precess to specified timestamp
2479 NcTimestamp ts1;
2480 ts1.SetEpoch(2000,"J");
2481 Precess(q,&ts1,ts);
2482
2483 // Nutation correction
2484 Nutate(q,ts);
2485
2486 // Convert from equatorial to horizontal coordinates
2487 SetHmatrix(ts);
2488 q=q.GetPrimed(&fH);
2489 }
2490
2491 if (frame=="loc")
2492 {
2493 // Get the signal in horizontal coordinates
2494 GetSignal(q,"hor",mode,ts,jref,type);
2495
2496 // Convert from horizontal to local-frame coordinates
2497 q=q.GetPrimed(&fL);
2498 }
2499
2500 r.Load(q);
2501 return sx;
2502}
2503
2504void NcAstrolab::GeoToHeliocentric(Double_t& R,Double_t& B,Double_t& L,NcTimestamp* ts,TString Bu,TString Lu)
2505{
2539
2540 if (!ts) ts=(NcTimestamp*)this;
2541
2542 // Convert the angles into radians
2543 B=ConvertAngle(B,Bu,"rad");
2544 L=ConvertAngle(L,Lu,"rad");
2545
2546 // The Carthesian Geocentric ecliptic coordinates of the object
2547 Double_t xg=R*cos(B)*cos(L);
2548 Double_t yg=R*cos(B)*sin(L);
2549 Double_t zg=R*sin(B);
2550
2551 // Get the Heliocentric ecliptic coordinates of the Earth
2552 Double_t r0,b0,l0;
2553 ts->Almanac(0,0,0,0,"Earth*",&l0,&b0,&r0);
2554
2555 l0=ConvertAngle(l0,"deg","rad");
2556 b0=ConvertAngle(b0,"deg","rad");
2557
2558 Double_t x0=r0*cos(b0)*cos(l0);
2559 Double_t y0=r0*cos(b0)*sin(l0);
2560 Double_t z0=r0*sin(b0);
2561
2562 // The Heliocentric Carthesian ecliptic coordinates of the object
2563 Double_t xh=xg+x0;
2564 Double_t yh=yg+y0;
2565 Double_t zh=zg+z0;
2566
2567 // Convert to Heliocentric distance, latitude and longitude
2568 Double_t Rh=sqrt(xh*xh+yh*yh+zh*zh);
2569 Double_t Bh=atan2(zh,sqrt(xh*xh+yh*yh));
2570 Double_t Lh=atan2(yh,xh);
2571
2572 Double_t twopi=2.*acos(-1.);
2573 while (Lh<0) { Lh+=twopi; }
2574 while (Lh>twopi) { Lh-=twopi; }
2575
2576 // Return the Heliocentric values in the original units
2577 R=Rh;
2578 B=ConvertAngle(Bh,"rad",Bu);
2579 L=ConvertAngle(Lh,"rad",Lu);
2580}
2581
2582void NcAstrolab::HelioToGeocentric(Double_t& R,Double_t& B,Double_t& L,NcTimestamp* ts,TString Bu,TString Lu)
2583{
2617
2618 if (!ts) ts=(NcTimestamp*)this;
2619
2620 // Convert the angles into radians
2621 B=ConvertAngle(B,Bu,"rad");
2622 L=ConvertAngle(L,Lu,"rad");
2623
2624 // The Carthesian Heliocentric ecliptic coordinates of the object
2625 Double_t xh=R*cos(B)*cos(L);
2626 Double_t yh=R*cos(B)*sin(L);
2627 Double_t zh=R*sin(B);
2628
2629 // Get the Heliocentric ecliptic coordinates of the Earth
2630 Double_t r0,b0,l0;
2631 ts->Almanac(0,0,0,0,"Earth*",&l0,&b0,&r0);
2632
2633 l0=ConvertAngle(l0,"deg","rad");
2634 b0=ConvertAngle(b0,"deg","rad");
2635
2636 Double_t x0=r0*cos(b0)*cos(l0);
2637 Double_t y0=r0*cos(b0)*sin(l0);
2638 Double_t z0=r0*sin(b0);
2639
2640 // The Geocentric Carthesian ecliptic coordinates of the object
2641 Double_t xg=xh-x0;
2642 Double_t yg=yh-y0;
2643 Double_t zg=zh-z0;
2644
2645 // Convert to Geocentric distance, latitude and longitude
2646 Double_t Rg=sqrt(xg*xg+yg*yg+zg*zg);
2647 Double_t Bg=atan2(zg,sqrt(xg*xg+yg*yg));
2648 Double_t Lg=atan2(yg,xg);
2649
2650 Double_t twopi=2.*acos(-1.);
2651 while (Lg<0) { Lg+=twopi; }
2652 while (Lg>twopi) { Lg-=twopi; }
2653
2654 // Return the Geocentric values in the original units
2655 R=Rg;
2656 B=ConvertAngle(Bg,"rad",Bu);
2657 L=ConvertAngle(Lg,"rad",Lu);
2658}
2659
2660NcSignal* NcAstrolab::GetSignal(Double_t& d,Double_t& a,TString au,Double_t& b,TString bu,TString frame,NcTimestamp* ts,Int_t jref,TString mode,Int_t type)
2661{
2732
2733 d=0;
2734 a=0;
2735 b=0;
2736
2737 Nc3Vector r;
2738 NcSignal* sx=GetSignal(r,frame,mode,ts,jref,type);
2739
2740 if (!sx) return 0;
2741
2742 // Retrieve the requested (a,d) values in the correct format
2743 Double_t vec[3];
2744 r.GetVector(vec,"sph","deg");
2745
2746 d=vec[0];
2747 if (d<=0) d=1;
2748 b=vec[1];
2749 a=vec[2];
2750
2751 if (frame=="equ" || frame=="gal" || frame=="ecl" || frame=="icr")
2752 {
2753 b=90.-vec[1];
2754 while (b<-90.)
2755 {
2756 b+=90.;
2757 }
2758 while (b>90.)
2759 {
2760 b-=90.;
2761 }
2762 }
2763
2764 if (frame=="hor")
2765 {
2766 a=180.-vec[2];
2767 }
2768
2769 while (a<-360.)
2770 {
2771 a+=360.;
2772 }
2773 while (a>360.)
2774 {
2775 a-=360.;
2776 }
2777
2778 // Interchange a and b to represent theta and phi, respectively, for local coordinates
2779 if (frame=="loc")
2780 {
2781 Double_t temp=a;
2782 a=b;
2783 b=temp;
2784 }
2785
2786 // Convert coordinates to appropriate format
2787 a=ConvertAngle(a,"deg",au);
2788 b=ConvertAngle(b,"deg",bu);
2789
2790 return sx;
2791}
2792
2793NcSignal* NcAstrolab::GetSignal(Double_t& d,Double_t& a,TString au,Double_t& b,TString bu,TString frame,NcTimestamp* ts,TString name,TString mode,Int_t type)
2794{
2866
2867 // Set c.q. update coordinates for Solar system objects
2868 SetSolarSystem(name,ts,type);
2869
2870 NcSignal* sx=0;
2871 Int_t j=GetSignalIndex(name,type);
2872 if (j>=0) sx=GetSignal(d,a,au,b,bu,frame,ts,j,mode,type);
2873 return sx;
2874}
2875
2876NcSignal* NcAstrolab::GetSignal(Double_t& d,Double_t& a,TString au,Double_t& b,TString bu,TString frame,TString s,Double_t e,Int_t jref,TString mode,Int_t type)
2877{
2952
2953 d=0;
2954 a=0;
2955 b=0;
2956
2957 if (s!="B" && s!="b" && s!="J" && s!="j") return 0;
2958
2959 NcTimestamp tx;
2960 tx.SetEpoch(e,s);
2961
2962 NcSignal* sx=GetSignal(d,a,au,b,bu,frame,&tx,jref,mode,type);
2963 return sx;
2964}
2965
2966NcSignal* NcAstrolab::GetSignal(Double_t& d,Double_t& a,TString au,Double_t& b,TString bu,TString frame,TString s,Double_t e,TString name,TString mode,Int_t type)
2967{
3043
3044 // Set c.q. update coordinates for Solar system objects
3045 NcTimestamp tx;
3046 tx.SetEpoch(e,s);
3047 SetSolarSystem(name,&tx,type);
3048
3049 NcSignal* sx=0;
3050 Int_t j=GetSignalIndex(name,type);
3051 if (j>=0) sx=GetSignal(d,a,au,b,bu,frame,s,e,j,mode,type);
3052 return sx;
3053}
3054
3055NcSignal* NcAstrolab::GetSignal(Int_t jref,Int_t type)
3056{
3077
3078 if (jref<0) return 0;
3079
3080 if (!jref) // For backward compatibility
3081 {
3082 jref=1;
3083 type=1;
3084 }
3085
3086 if (!type && !fRefs) return 0;
3087 if (type && !fSigs) return 0;
3088
3089 NcSignal* sx=0;
3090 if (type)
3091 {
3092 if (jref<=fSigs->GetSize()) sx=(NcSignal*)fSigs->At(jref-1);
3093 }
3094 else
3095 {
3096 if (jref<=fRefs->GetSize()) sx=(NcSignal*)fRefs->At(jref-1);
3097 }
3098 return sx;
3099}
3100
3101NcSignal* NcAstrolab::GetSignal(TString name,Int_t type,NcTimestamp* ts)
3102{
3121
3122 NcSignal* sx=0;
3123 Int_t j=GetSignalIndex(name,type);
3124
3125 if (j==-1) // Set and store info for the requested Solar system object if not already stored
3126 {
3127 SetSolarSystem(name,ts,type);
3128 j=GetSignalIndex(name,type);
3129 }
3130
3131 if (j>=0) sx=GetSignal(j,type);
3132 return sx;
3133}
3134
3135Int_t NcAstrolab::RemoveRefSignal(Int_t j,Int_t compress)
3136{
3158
3159 Int_t nrem=0;
3160
3161 if (!fRefs) return 0;
3162
3163 // Clearing of the complete storage
3164 if (!j)
3165 {
3166 nrem=fRefs->GetEntries();
3167 delete fRefs;
3168 fRefs=0;
3169 return nrem;
3170 }
3171
3172 // Removing a specific reference signal
3173 if (j>0 && j<=fRefs->GetSize())
3174 {
3175 TObject* obj=fRefs->RemoveAt(j-1);
3176 if (obj)
3177 {
3178 delete obj;
3179 nrem++;
3180 }
3181 }
3182
3183 // Compression of the storage array
3184 if (compress) fRefs->Compress();
3185
3186 return nrem;
3187}
3188
3189Int_t NcAstrolab::RemoveRefSignal(TString name,Int_t compress)
3190{
3210
3211 Int_t nrem=0;
3212
3213 Int_t j=GetSignalIndex(name);
3214 if (j>0) nrem=RemoveRefSignal(j,compress);
3215
3216 return nrem;
3217}
3218
3219Int_t NcAstrolab::RemoveSignal(Int_t j,Int_t type,Int_t compress)
3220{
3240
3241 Int_t nrem=0;
3242
3243 TObjArray* arr=fRefs;
3244 if (type) arr=fSigs;
3245
3246 if (!arr) return nrem;
3247
3248 // Clearing of the complete "type" storage
3249 if (!j)
3250 {
3251 nrem=arr->GetEntries();
3252 delete arr;
3253 if (type)
3254 {
3255 fSigs=0;
3256 fNen[1]=0;
3257 }
3258 else
3259 {
3260 fRefs=0;
3261 fNen[0]=0;
3262 }
3263 return nrem;
3264 }
3265
3266 // Removing the specified signal
3267 if (j>0 && j<=arr->GetSize())
3268 {
3269 TObject* obj=arr->RemoveAt(j-1);
3270 if (obj)
3271 {
3272 delete obj;
3273 nrem++;
3274 }
3275 }
3276
3277 // Compression of the storage array
3278 if (compress)
3279 {
3280 arr->Compress();
3281 Int_t n=arr->GetEntries();
3282 arr->Expand(n);
3283 }
3284
3285 return nrem;
3286}
3287
3288Int_t NcAstrolab::RemoveSignal(TString name,Int_t type,Int_t compress)
3289{
3312
3313 Int_t nrem=0;
3314
3315 if (name=="") return nrem;
3316
3317 if (name=="*")
3318 {
3319 nrem=RemoveSignal(0,type,compress);
3320 }
3321 else
3322 {
3323 Int_t j=GetSignalIndex(name,type);
3324 if (j>0) nrem=RemoveSignal(j,type,compress);
3325 }
3326
3327 return nrem;
3328}
3329
3330Int_t NcAstrolab::RemoveSignals(TString name,Int_t type,Int_t compress)
3331{
3354
3355 Int_t nrem=0;
3356
3357 if (name=="") return 0;
3358
3359 if (name=="*")
3360 {
3361 nrem=RemoveSignal(0,type,compress);
3362 }
3363 else
3364 {
3365 TObjArray* arr=fRefs;
3366 if (type) arr=fSigs;
3367
3368 if (!arr) return 0;
3369
3370 NcSignal* sx=0;
3371 TString namex="";
3372 Int_t nremx=0;
3373 for (Int_t j=1; j<=arr->GetSize(); j++)
3374 {
3375 sx=GetSignal(j,type);
3376 if (!sx) continue;
3377
3378 namex=sx->GetName();
3379 if (!namex.Contains(name)) continue;
3380
3381 nremx=RemoveSignal(j,type,0);
3382 if (nremx) nrem++;
3383 }
3384
3385 // Compression of the storage array
3386 if (compress)
3387 {
3388 arr->Compress();
3389 Int_t n=arr->GetEntries();
3390 arr->Expand(n);
3391 }
3392 }
3393
3394 return nrem;
3395}
3396
3397Int_t NcAstrolab::GetSignalIndex(TString name,Int_t type)
3398{
3411
3412 if (name=="") return -1;
3413
3414 Int_t index=-1;
3415
3416 TObjArray* arr=fRefs;
3417 if (type) arr=fSigs;
3418
3419 if (!arr) return -1;
3420
3421 for (Int_t i=0; i<arr->GetSize(); i++)
3422 {
3423 NcSignal* sx=(NcSignal*)arr->At(i);
3424 if (!sx) continue;
3425
3426 if (name==sx->GetName())
3427 {
3428 index=i+1;
3429 break;
3430 }
3431 }
3432
3433 return index;
3434}
3435
3437{
3448
3449 if (!s) return -1;
3450
3451 Int_t index=-1;
3452
3453 TObjArray* arr=fRefs;
3454 if (type) arr=fSigs;
3455
3456 if (!arr) return -1;
3457
3458 for (Int_t i=0; i<arr->GetSize(); i++)
3459 {
3460 NcSignal* sx=(NcSignal*)arr->At(i);
3461 if (!sx) continue;
3462
3463 if (sx==s)
3464 {
3465 index=i+1;
3466 break;
3467 }
3468 }
3469
3470 return index;
3471}
3472
3473void NcAstrolab::PrintSignal(TString frame,TString mode,NcTimestamp* ts,Int_t ndig,Int_t jref,TString emode,Int_t type,Bool_t align)
3474{
3553
3554 NcSignal* sx=GetSignal(jref,type);
3555
3556 if (!sx) return;
3557
3558 if (!ts) ts=sx->GetTimestamp();
3559
3560 Nc3Vector r;
3561 GetSignal(r,frame,mode,ts,jref,type);
3562
3563 // Local Hour Angle of the signal
3564 Double_t lha=GetHourAngle("A",ts,jref,type);
3565 TString slha="LAHA";
3566 if (mode=="M" || mode=="m")
3567 {
3568 lha=GetHourAngle("M",ts,jref,type);
3569 slha="LMHA";
3570 }
3571 else if ((mode=="B" || mode=="b" || mode=="J" || mode=="j") && emode=="M")
3572 {
3573 lha=GetHourAngle("M",ts,jref,type);
3574 slha="LMHA";
3575 }
3576
3577 if (frame=="equ")
3578 {
3579 Double_t a,d;
3580 d=90.-r.GetX(2,"sph","deg");
3581 a=r.GetX(3,"sph","rad");
3582 if (mode=="B" || mode=="b") mode="B1950";
3583 if (mode=="J" || mode=="j") mode="J2000";
3584 cout << "Equatorial (" << mode.Data() <<") | a :";
3585 if (!align) {cout << " ";} PrintAngle(a,"rad","hms",ndig,align);
3586 if (!align) {cout << " ";} PrintAngle(a,"rad","deg",ndig,align);
3587 cout << " | b :";
3588 if (!align) {cout << " ";} PrintAngle(d,"deg","dms",ndig,align);
3589 if (!align) {cout << " ";} PrintAngle(d,"deg","deg",ndig,align);
3590 cout << " | " << slha.Data() << " : ";
3591 PrintAngle(lha,"deg","hms",ndig,align);
3592 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3593 }
3594
3595 if (frame=="gal")
3596 {
3597 Double_t l,b;
3598 b=90.-r.GetX(2,"sph","deg");
3599 l=r.GetX(3,"sph","deg");
3600 cout << "Galactic | l :";
3601 if (!align) {cout << " ";} PrintAngle(l,"deg","deg",ndig,align);
3602 if (!align) {cout << " ";} PrintAngle(l,"deg","dms",ndig,align);
3603 cout << " | b :";
3604 if (!align) {cout << " ";} PrintAngle(b,"deg","deg",ndig,align);
3605 if (!align) {cout << " ";} PrintAngle(b,"deg","dms",ndig,align);
3606 cout << " | " << slha.Data() << " : ";
3607 PrintAngle(lha,"deg","hms",ndig,align);
3608 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3609 }
3610
3611 if (frame=="icr")
3612 {
3613 Double_t l,b;
3614 b=90.-r.GetX(2,"sph","deg");
3615 l=r.GetX(3,"sph","deg");
3616 cout << "ICRS | l :";
3617 if (!align) {cout << " ";} PrintAngle(l,"deg","deg",ndig,align);
3618 if (!align) {cout << " ";} PrintAngle(l,"deg","dms",ndig,align);
3619 cout << " | b :";
3620 if (!align) {cout << " ";} PrintAngle(b,"deg","deg",ndig,align);
3621 if (!align) {cout << " ";} PrintAngle(b,"deg","dms",ndig,align);
3622 cout << " | " << slha.Data() << " : ";
3623 PrintAngle(lha,"deg","hms",ndig,align);
3624 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3625 }
3626
3627 if (frame=="ecl")
3628 {
3629 Double_t l,b;
3630 b=90.-r.GetX(2,"sph","deg");
3631 l=r.GetX(3,"sph","deg");
3632 cout << "Geocentric ecliptic | l :";
3633 if (!align) {cout << " ";} PrintAngle(l,"deg","deg",ndig,align);
3634 if (!align) {cout << " ";} PrintAngle(l,"deg","dms",ndig,align);
3635 cout << " | b :";
3636 if (!align) {cout << " ";} PrintAngle(b,"deg","deg",ndig,align);
3637 if (!align) {cout << " ";} PrintAngle(b,"deg","dms",ndig,align);
3638 cout << " | " << slha.Data() << " : ";
3639 PrintAngle(lha,"deg","hms",ndig,align);
3640 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3641 }
3642
3643 if (frame=="hor")
3644 {
3645 Double_t alt=90.-r.GetX(2,"sph","deg");
3646 Double_t azi=180.-r.GetX(3,"sph","deg");
3647 while (azi>360)
3648 {
3649 azi-=360.;
3650 }
3651 while (azi<0)
3652 {
3653 azi+=360.;
3654 }
3655 cout << "Horizontal | azi :";
3656 if (!align) {cout << " ";} PrintAngle(azi,"deg","deg",ndig,align);
3657 if (!align) {cout << " ";} PrintAngle(azi,"deg","dms",ndig,align);
3658 cout << " | alt :";
3659 if (!align) {cout << " ";} PrintAngle(alt,"deg","deg",ndig,align);
3660 if (!align) {cout << " ";} PrintAngle(alt,"deg","dms",ndig,align);
3661 cout << " | " << slha.Data() << " : ";
3662 PrintAngle(lha,"deg","hms",ndig,align);
3663 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3664 }
3665
3666 if (frame=="loc")
3667 {
3668 Double_t theta=r.GetX(2,"sph","deg");
3669 Double_t phi=r.GetX(3,"sph","deg");
3670 cout << "Local-frame | phi :";
3671 if (!align) {cout << " ";} PrintAngle(phi,"deg","deg",ndig,align);
3672 if (!align) {cout << " ";} PrintAngle(phi,"deg","dms",ndig,align);
3673 cout << " | theta :";
3674 if (!align) {cout << " ";} PrintAngle(theta,"deg","deg",ndig,align);
3675 if (!align) {cout << " ";} PrintAngle(theta,"deg","dms",ndig,align);
3676 cout << " | " << slha.Data() << " : ";
3677 PrintAngle(lha,"deg","hms",ndig,align);
3678 cout << " "; PrintAngle(lha,"deg","deg",ndig,align);
3679 }
3680
3681 cout << " |";
3682
3683 TString name=sx->GetName();
3684 if (name != "") cout << " " << name.Data();
3685}
3686
3687void NcAstrolab::PrintSignal(TString frame,TString mode,NcTimestamp* ts,Int_t ndig,TString name,TString emode,Int_t type,Bool_t align)
3688{
3764
3765 // Set c.q. update coordinates for Solar system objects
3766 SetSolarSystem(name,ts,type);
3767
3768 Int_t j=GetSignalIndex(name,type);
3769 if (j>=0) PrintSignal(frame,mode,ts,ndig,j,emode,type,align);
3770}
3771
3772void NcAstrolab::ListSignals(TString frame,TString mode,Int_t ndig,TString emode,Int_t nmax,Int_t j,Int_t type,NcTimestamp* ts,TString name)
3773{
3845
3846 Int_t iprint=0;
3847 Int_t width=0; // Width for printing of the index
3848 if (nmax>0) width=log10(nmax);
3849 if (nmax<0)
3850 {
3851 Int_t maxref=0;
3852 if (fRefs) maxref=fRefs->GetSize();
3853 Int_t maxsig=0;
3854 if (fSigs) maxsig=fSigs->GetSize();
3855 Int_t maxj=maxref;
3856 if (maxsig>maxj) maxj=maxsig;
3857 if (maxj>0) width=log10(maxj);
3858 }
3859 width++;
3860
3861 NcSignal* sx=0;
3862 NcTimestamp* tx=0;
3863
3864 Int_t dform=1;
3865 if (mode=="T" || mode=="t") dform=-1;
3866 if ((mode=="B" || mode=="b" || mode=="J" || mode=="j") && emode=="T") dform=-1;
3867
3868 if (j>0) sx=GetSignal(j,1);
3869 if (sx)
3870 {
3871 tx=sx->GetTimestamp();
3872 if (!tx) tx=ts;
3873 if (!tx) tx=(NcTimestamp*)this;
3874 printf(" *%-s::ListSignals* Name : %-s Title : %-s \n",ClassName(),GetName(),GetTitle());
3875 if (fTscmode!=2)
3876 {
3877 cout << " Timestamp of the measurement stored at index=" << j;
3878 }
3879 else
3880 {
3881 cout << " *Scrambled* timestamp of the measurement stored at index=" << j;
3882 }
3883 cout << " (Lab time offset w.r.t. UT : "; PrintTime(fToffset,12); cout << ")" << endl;
3884 tx->Date(dform,fToffset);
3885 tx->Date(4);
3886 cout << " Corresponding location of this measurement" << endl;
3887 cout << " "; PrintSignal(frame,mode,tx,ndig,j,emode,1); cout << endl;
3888 iprint=1;
3889 }
3890
3891 TObjArray* arr=0;
3892 Int_t nstored=0;
3893 Int_t jlist=0;
3894 Int_t test=type;
3895 while (test<2)
3896 {
3897 if (test==0)
3898 {
3899 type=0;
3900 arr=fRefs;
3901 test=999;
3902 }
3903 if (test==1)
3904 {
3905 type=1;
3906 arr=fSigs;
3907 test=999;
3908 }
3909 if (test<0)
3910 {
3911 type=0;
3912 arr=fRefs;
3913 test=1;
3914 }
3915
3916 if (!arr) continue;
3917
3918 nstored=arr->GetEntries();
3919 jlist=0;
3920 TString namex="";
3921 for (Int_t i=1; i<=arr->GetSize(); i++)
3922 {
3923 sx=GetSignal(i,type);
3924 if (!sx) continue;
3925
3926 jlist++;
3927 if (nmax>=0 && jlist>nmax) break;
3928
3929 // Check for the name pattern
3930 namex=sx->GetName();
3931 if (name!="*" && !namex.Contains(name)) continue;
3932
3933 if (!iprint)
3934 {
3935 printf(" *%-s::ListSignals* Name : %-s Title : %-s \n",ClassName(),GetName(),GetTitle());
3936 if (j==0) tx=ts;
3937 if (tx)
3938 {
3939 cout << " User provided timestamp (Lab time offset w.r.t. UT : "; PrintTime(fToffset,12); cout << ")";
3940 cout << endl;
3941 tx->Date(dform,fToffset);
3942 tx->Date(4);
3943 }
3944 else
3945 {
3946 tx=(NcTimestamp*)this;
3947 if (j>=0)
3948 {
3949 cout << " Current timestamp of the laboratory (Lab time offset w.r.t. UT : "; PrintTime(fToffset,12); cout << ")";
3950 cout << endl;
3951 tx->Date(dform,fToffset);
3952 tx->Date(4);
3953 }
3954 }
3955 iprint=1;
3956 }
3957 if (iprint==1)
3958 {
3959 if (nmax<0 || nmax>=nstored)
3960 {
3961 if (!type)
3962 {
3963 if (j>=0)
3964 {
3965 cout << " === All stored reference signals according to the above timestamp ===" << endl;
3966 }
3967 else
3968 {
3969 cout << " === All stored reference signals according to their actual recorded timestamp ===" << endl;
3970 }
3971 }
3972 else
3973 {
3974 if (fTscmode!=2)
3975 {
3976 cout << " === All stored measurements according to their actual observation timestamp ===" << endl;
3977 }
3978 else
3979 {
3980 cout << " === All stored measurements according to their *scrambled* observation timestamp ===" << endl;
3981 cout << " === Time scrambling was performed by adding dt from the interval [dtmin,dtmax] to their actual timestamp" << endl;
3982 cout << " === dtmin : " << fTscmin << " dtmax : " << fTscmax << " sec.";
3983 if (fTscfunc)
3984 {
3985 cout << " Randomising TF1 function " << fTscfunc->GetName() << " was used." << endl;
3986 }
3987 else
3988 {
3989 cout << " Uniform randomisation was used." << endl;
3990 }
3991 }
3992 }
3993 }
3994 else
3995 {
3996 if (!type)
3997 {
3998 if (j>=0)
3999 {
4000 cout << " === The first " << nmax << " stored reference signals according to the above timestamp ===" << endl;
4001 }
4002 else
4003 {
4004 cout << " === The first " << nmax << " stored reference signals according to their actual recorded timestamp ===" << endl;
4005 }
4006 }
4007 else
4008 {
4009 if (fTscmode!=2)
4010 {
4011 cout << " === The first " << nmax << " stored measurements according to their actual observation timestamp ===" << endl;
4012 }
4013 else
4014 {
4015 cout << " === The first " << nmax << " stored measurements according to their *scrambled* observation timestamp ===" << endl;
4016 cout << " === Time scrambling was performed by adding dt from the interval [dtmin,dtmax] to their actual timestamp" << endl;
4017 cout << " === dtmin : " << fTscmin << " dtmax : " << fTscmax << " sec.";
4018 if (fTscfunc)
4019 {
4020 cout << " Randomising TF1 function " << fTscfunc->GetName() << " was used." << endl;
4021 }
4022 else
4023 {
4024 cout << " Uniform randomisation was used." << endl;
4025 }
4026 }
4027 }
4028 }
4029 iprint=2;
4030 }
4031 if (type==1 || (!type && j<0)) tx=0;
4032 printf(" Index : %*d ",width,i); PrintSignal(frame,mode,tx,ndig,i,emode,type,kTRUE); printf("\n");
4033 }
4034 iprint=1;
4035 }
4036}
4037
4039{
4064
4065 // Convert back to J2000 values
4066 Nc3Vector r0;
4067 SetPmatrix(ts1);
4068 r0=r.GetUnprimed(&fP);
4069
4070 // Precess to the specified timestamp
4071 if (!ts2) ts2=(NcTimestamp*)this;
4072 SetPmatrix(ts2);
4073 r=r0.GetPrimed(&fP);
4074}
4075
4077{
4097
4098 // Nutation correction for the specified timestamp
4099 if (!ts) ts=(NcTimestamp*)this;
4100 SetNmatrix(ts);
4101 r=r.GetPrimed(&fN);
4102}
4103
4105{
4114
4115 Double_t pi=acos(-1.);
4116
4117 // Parameters in mas
4118 Double_t a=-14.6;
4119 Double_t x=-16.6170;
4120 Double_t e=-6.8192;
4121
4122 // Convert to radians
4123 a*=pi/(180.*3600.*1000.);
4124 x*=pi/(180.*3600.*1000.);
4125 e*=pi/(180.*3600.*1000.);
4126
4127 Double_t mat[9];
4128 mat[0]=1.-0.5*(a*a+x*x);
4129 mat[1]=a;
4130 mat[2]=-x;
4131 mat[3]=-a-e*x;
4132 mat[4]=1.-0.5*(a*a+e*e);
4133 mat[5]=-e;
4134 mat[6]=x-e*a;
4135 mat[7]=e+x*a;
4136 mat[8]=1.-0.5*(e*e+x*x);
4137
4138 fB.SetMatrix(mat);
4139 fBias=1;
4140}
4141
4143{
4153
4154 Double_t mat[9]={0,0,0,0,0,0,0,0,0};
4155 if (!ts)
4156 {
4157 fP.SetMatrix(mat);
4158 return;
4159 }
4160
4161 Double_t pi=acos(-1.);
4162
4163 Double_t t=(ts->GetJD()-2451545.0)/36525.; // Julian centuries since J2000.0
4164
4165 // Parameters for the precession matrix in arcseconds
4166 Double_t eps0=84381.406; // Mean ecliptic obliquity at J2000.0
4167 Double_t psi=5038.481507*t-1.0790069*pow(t,2)-0.00114045*pow(t,3)+0.000132851*pow(t,4)
4168 -0.0000000951*pow(t,4);
4169 Double_t om=eps0-0.025754*t+0.0512623*pow(t,2)-0.00772503*pow(t,3)-0.000000467*pow(t,4)
4170 +0.0000003337*pow(t,5);
4171 Double_t chi=10.556403*t-2.3814292*pow(t,2)-0.00121197*pow(t,3)+0.000170663*pow(t,4)
4172 -0.0000000560*pow(t,5);
4173
4174 // Convert to radians
4175 eps0*=pi/(180.*3600.);
4176 psi*=pi/(180.*3600.);
4177 om*=pi/(180.*3600.);
4178 chi*=pi/(180.*3600.);
4179
4180 Double_t s1=sin(eps0);
4181 Double_t s2=sin(-psi);
4182 Double_t s3=sin(-om);
4183 Double_t s4=sin(chi);
4184 Double_t c1=cos(eps0);
4185 Double_t c2=cos(-psi);
4186 Double_t c3=cos(-om);
4187 Double_t c4=cos(chi);
4188
4189 mat[0]=c4*c2-s2*s4*c3;
4190 mat[1]=c4*s2*c1+s4*c3*c2*c1-s1*s4*s3;
4191 mat[2]=c4*s2*s1+s4*c3*c2*s1+c1*s4*s3;
4192 mat[3]=-s4*c2-s2*c4*c3;
4193 mat[4]=-s4*s2*c1+c4*c3*c2*c1-s1*c4*s3;
4194 mat[5]=-s4*s2*s1+c4*c3*c2*s1+c1*c4*s3;
4195 mat[6]=s2*s3;
4196 mat[7]=-s3*c2*c1-s1*c3;
4197 mat[8]=-s3*c2*s1+c3*c1;
4198
4199 fP.SetMatrix(mat);
4200}
4201
4203{
4212
4213 Double_t mat[9]={0,0,0,0,0,0,0,0,0};
4214 if (!ts)
4215 {
4216 fN.SetMatrix(mat);
4217 return;
4218 }
4219
4220 Double_t pi=acos(-1.);
4221
4222 Double_t dpsi,deps,eps;
4223 ts->Almanac(&dpsi,&deps,&eps);
4224
4225 // Convert to radians
4226 dpsi*=pi/(180.*3600.);
4227 deps*=pi/(180.*3600.);
4228 eps*=pi/(180.*3600.);
4229
4230 Double_t s1=sin(eps);
4231 Double_t s2=sin(-dpsi);
4232 Double_t s3=sin(-(eps+deps));
4233 Double_t c1=cos(eps);
4234 Double_t c2=cos(-dpsi);
4235 Double_t c3=cos(-(eps+deps));
4236
4237 mat[0]=c2;
4238 mat[1]=s2*c1;
4239 mat[2]=s2*s1;
4240 mat[3]=-s2*c3;
4241 mat[4]=c3*c2*c1-s1*s3;
4242 mat[5]=c3*c2*s1+c1*s3;
4243 mat[6]=s2*s3;
4244 mat[7]=-s3*c2*c1-s1*c3;
4245 mat[8]=-s3*c2*s1+c3*c1;
4246
4247 fN.SetMatrix(mat);
4248}
4249
4250void NcAstrolab::SetGmatrix(TString mode)
4251{
4264
4265 Nc3Vector x; // The Galactic x-axis in the equatorial frame
4266 Nc3Vector y; // The Galactic y-axis in the equatorial frame
4267 Nc3Vector z; // The Galactic z-axis in the equatorial frame
4268
4269 Double_t a,d;
4270 Double_t vec[3]={1,0,0};
4271
4272 fGal=1; // Set flag to indicate B1950 matrix values
4273
4274 // B1950 equatorial coordinates of the North Galactic Pole (NGP)
4275 a=124900.;
4276 d=272400.;
4277 a=ConvertAngle(a,"hms","deg");
4278 d=ConvertAngle(d,"dms","deg");
4279 vec[1]=90.-d;
4280 vec[2]=a;
4281 z.SetVector(vec,"sph","deg");
4282
4283 // B1950 equatorial coordinates of the Galactic l=b=0 point
4284 a=174224.;
4285 d=-285500.;
4286 a=ConvertAngle(a,"hms","deg");
4287 d=ConvertAngle(d,"dms","deg");
4288 vec[1]=90.-d;
4289 vec[2]=a;
4290 x.SetVector(vec,"sph","deg");
4291
4292 // Precess to the corresponding J2000 values if requested
4293 if (mode=="J")
4294 {
4295 fGal=2; // Set flag to indicate J2000 matrix values
4296 NcTimestamp t1;
4297 t1.SetEpoch(1950,"B");
4298 NcTimestamp t2;
4299 t2.SetEpoch(2000,"J");
4300 Precess(z,&t1,&t2);
4301 Precess(x,&t1,&t2);
4302 }
4303
4304 // The Galactic y-axis is determined for the right handed frame
4305 y=z.Cross(x);
4306
4307 fG.SetAngles(x.GetX(2,"sph","deg"),x.GetX(3,"sph","deg"),
4308 y.GetX(2,"sph","deg"),y.GetX(3,"sph","deg"),
4309 z.GetX(2,"sph","deg"),z.GetX(3,"sph","deg"));
4310}
4311
4313{
4322
4323 Double_t dpsi,deps,eps;
4324 ts->Almanac(&dpsi,&deps,&eps);
4325
4326 // Convert to degrees
4327 eps/=3600.;
4328
4329 // Positions of the ecliptic axes w.r.t. the equatorial ones
4330 // at the moment of the specified timestamp
4331 Double_t theta1=90; // Ecliptic x-axis
4332 Double_t phi1=0;
4333 Double_t theta2=90.-eps; //Ecliptic y-axis
4334 Double_t phi2=90;
4335 Double_t theta3=eps; // Ecliptic z-axis
4336 Double_t phi3=270;
4337
4338 fE.SetAngles(theta1,phi1,theta2,phi2,theta3,phi3);
4339}
4340
4342{
4354
4355 Nc3Vector x; // The (South pointing) horizontal x-axis in the equatorial frame
4356 Nc3Vector y; // The (East pointing) horizontal y-axis in the equatorial frame
4357 Nc3Vector z; // The (Zenith pointing) horizontal z-axis in the equatorial frame
4358
4359 Double_t l,b;
4360 GetLabPosition(l,b,"deg");
4361
4362 Double_t a;
4363 Double_t vec[3]={1,0,0};
4364
4365 // Equatorial coordinates of the horizontal z-axis
4366 // at the moment of the specified timestamp
4367 a=ts->GetLAST(fToffset);
4368 a*=15.; // Convert fractional hours to degrees
4369 vec[1]=90.-b;
4370 vec[2]=a;
4371 z.SetVector(vec,"sph","deg");
4372
4373 // Equatorial coordinates of the horizontal x-axis
4374 // at the moment of the specified timestamp
4375 vec[1]=180.-b;
4376 vec[2]=a;
4377 x.SetVector(vec,"sph","deg");
4378
4379 // The horizontal y-axis is determined for the right handed frame
4380 y=z.Cross(x);
4381
4382 fH.SetAngles(x.GetX(2,"sph","deg"),x.GetX(3,"sph","deg"),
4383 y.GetX(2,"sph","deg"),y.GetX(3,"sph","deg"),
4384 z.GetX(2,"sph","deg"),z.GetX(3,"sph","deg"));
4385}
4386
4387void NcAstrolab::SetLocalFrame(Double_t t1,Double_t p1,Double_t t2,Double_t p2,Double_t t3,Double_t p3)
4388{
4417
4418 // Set the matrix for the conversion of our reference frame coordinates
4419 // into the local-frame ones.
4420
4421 fL.SetAngles(t1,p1,t2,p2,t3,p3);
4422
4423 // Store the local user frame axes orientations w.r.t. the standard local Horizon (zen,azi) frame
4424 fAxes[0]=t1;
4425 fAxes[1]=p1;
4426 fAxes[2]=t2;
4427 fAxes[3]=p2;
4428 fAxes[4]=t3;
4429 fAxes[5]=p3;
4430}
4431
4433{
4443
4444 arr[0]=fAxes[0];
4445 arr[1]=fAxes[1];
4446 arr[2]=fAxes[2];
4447 arr[3]=fAxes[3];
4448 arr[4]=fAxes[4];
4449 arr[5]=fAxes[5];
4450}
4451
4452Double_t NcAstrolab::ConvertAngle(Double_t a,TString in,TString out) const
4453{
4474
4475 if (in==out) return a;
4476
4477 // Convert input to its absolute value in (fractional) degrees.
4478 Double_t pi=acos(-1.);
4479 Double_t epsilon=1.e-12; // Accuracy in (arc)seconds
4480 Int_t word=0,ddd=0,hh=0,mm=0,ss=0;
4481 Double_t s=0;
4482
4483 Double_t b=fabs(a);
4484
4485 if (in=="rad") b*=180./pi;
4486
4487 if (in=="hrs") b*=15.;
4488
4489 if (in=="dms")
4490 {
4491 word=Int_t(b);
4492 ddd=word/10000;
4493 word=word%10000;
4494 mm=word/100;
4495 ss=word%100;
4496 s=b-Double_t(ddd*10000+mm*100+ss);
4497 b=Double_t(ddd)+Double_t(mm)/60.+(Double_t(ss)+s)/3600.;
4498 }
4499
4500 if (in=="hms")
4501 {
4502 word=Int_t(b);
4503 hh=word/10000;
4504 word=word%10000;
4505 mm=word/100;
4506 ss=word%100;
4507 s=b-Double_t(hh*10000+mm*100+ss);
4508 b=15.*(Double_t(hh)+Double_t(mm)/60.+(Double_t(ss)+s)/3600.);
4509 }
4510
4511 while (b>360)
4512 {
4513 b-=360.;
4514 }
4515
4516 if (out=="rad") b*=pi/180.;
4517
4518 if (out=="hrs") b/=15.;
4519
4520 if (out=="dms")
4521 {
4522 ddd=Int_t(b);
4523 b=b-Double_t(ddd);
4524 b*=60.;
4525 mm=Int_t(b);
4526 b=b-Double_t(mm);
4527 b*=60.;
4528 ss=Int_t(b);
4529 s=b-Double_t(ss);
4530 if (s>(1.-epsilon))
4531 {
4532 s=0.;
4533 ss++;
4534 }
4535 while (ss>=60)
4536 {
4537 ss-=60;
4538 mm++;
4539 }
4540 while (mm>=60)
4541 {
4542 mm-=60;
4543 ddd++;
4544 }
4545 while (ddd>=360)
4546 {
4547 ddd-=360;
4548 }
4549 b=Double_t(10000*ddd+100*mm+ss)+s;
4550 }
4551
4552 if (out=="hms")
4553 {
4554 b/=15.;
4555 hh=Int_t(b);
4556 b=b-Double_t(hh);
4557 b*=60.;
4558 mm=Int_t(b);
4559 b=b-Double_t(mm);
4560 b*=60.;
4561 ss=Int_t(b);
4562 s=b-Double_t(ss);
4563 if (s>(1.-epsilon))
4564 {
4565 s=0.;
4566 ss++;
4567 }
4568 while (ss>=60)
4569 {
4570 ss-=60;
4571 mm++;
4572 }
4573 while (mm>=60)
4574 {
4575 mm-=60;
4576 hh++;
4577 }
4578 while (hh>=24)
4579 {
4580 hh-=24;
4581 }
4582 b=Double_t(10000*hh+100*mm+ss)+s;
4583 }
4584
4585 if (a<0) b=-b;
4586
4587 return b;
4588}
4589
4590Double_t NcAstrolab::GetSolidAngle(Double_t thetamin,Double_t thetamax,TString tu,Double_t phimin,Double_t phimax,TString pu) const
4591{
4606
4607 Double_t omega=0;
4608
4609 Double_t th1=ConvertAngle(thetamin,tu,"rad");
4610 Double_t th2=ConvertAngle(thetamax,tu,"rad");
4611 Double_t ph1=ConvertAngle(phimin,pu,"rad");
4612 Double_t ph2=ConvertAngle(phimax,pu,"rad");
4613
4614 omega=(ph2-ph1)*(cos(th1)-cos(th2));
4615 if (omega<0) omega=-omega;
4616
4617 return omega;
4618}
4619
4620Double_t NcAstrolab::GetHourAngle(TString mode,NcTimestamp* ts,Int_t jref,Int_t type)
4621{
4655
4656 if (!ts) ts=(NcTimestamp*)this;
4657
4658 // Get corrected right ascension and declination for the specified timestamp.
4659 Double_t d,a,b;
4660 if (mode=="M" || mode=="m") GetSignal(d,a,"deg",b,"deg","equ",ts,jref,"M",type);
4661 if (mode=="A" || mode=="a") GetSignal(d,a,"deg",b,"deg","equ",ts,jref,"T",type);
4662
4663 a/=15.; // Convert a to fractional hours
4664 Double_t ha=0;
4665 if (mode=="M" || mode=="m") ha=ts->GetLMST(fToffset)-a;
4666 if (mode=="A" || mode=="a") ha=ts->GetLAST(fToffset)-a;
4667 ha*=15.; // Convert to (fractional) degrees
4668
4669 // Project to the interval [-180,180]
4670 while (ha<-180)
4671 {
4672 ha+=360.;
4673 }
4674 while (ha>180)
4675 {
4676 ha-=360.;
4677 }
4678
4679 return ha;
4680}
4681
4682void NcAstrolab::SetLT(Int_t y,Int_t m,Int_t d,Int_t hh,Int_t mm,Int_t ss,Int_t ns,Int_t ps)
4683{
4705
4706 SetLT(fToffset,y,m,d,hh,mm,ss,ns,ps);
4707}
4708
4709void NcAstrolab::SetLT(Int_t y,Int_t m,Int_t d,Int_t hh,Int_t mm,Double_t s)
4710{
4731
4732 SetLT(fToffset,y,m,d,hh,mm,s);
4733}
4734
4735void NcAstrolab::SetLT(Int_t y,Int_t m,Int_t d,TString time)
4736{
4755
4756 SetLT(fToffset,y,m,d,time);
4757}
4758
4759void NcAstrolab::SetLT(TString date,TString time,Int_t mode)
4760{
4781
4782 SetLT(fToffset,date,time,mode);
4783}
4784
4785void NcAstrolab::SetLT(Int_t y,Int_t d,Int_t s,Int_t ns,Int_t ps)
4786{
4811
4812 SetLT(fToffset,y,d,s,ns,ps);
4813}
4814
4815Double_t NcAstrolab::GetDifference(Int_t j,TString au,Double_t& dt,TString tu,Int_t mode,Int_t* ia,Int_t* it)
4816{
4862
4863 Double_t da=999;
4864 dt=1.e30;
4865
4866 if (ia) *ia=0;
4867 if (it) *it=0;
4868
4869 if (j<0) return da;
4870
4871 NcDevice matches;
4872 Int_t nhits=0;
4873 NcSignal* sx=0;
4874 if (j) // Space and time difference w.r.t. a specific reference signal
4875 {
4876 MatchSignals(matches,da,au,dt,tu,mode,j,j,0,1,1,1);
4877 nhits=matches.GetNhits();
4878 if (nhits)
4879 {
4880 da=matches.GetSignal(1);
4881 dt=matches.GetSignal(2);
4882 if (ia) *ia=j;
4883 if (it) *it=j;
4884 }
4885 }
4886 else // Minimal space and time difference encountered over all reference signals
4887 {
4888 MatchSignals(matches,da,au,dt,tu,mode,1,0,0,1,1,1);
4889 nhits=matches.GetNhits();
4890 if (nhits)
4891 {
4892 da=matches.GetSignal(1);
4893 dt=matches.GetSignal(2);
4894 if (ia)
4895 {
4896 Int_t ipsi=matches.GetSignal("ipsi");
4897 sx=matches.GetHit(ipsi);
4898 if (sx) *ia=sx->GetSignal("index1");
4899 }
4900 if (it)
4901 {
4902 Int_t idt=matches.GetSignal("idt");
4903 sx=matches.GetHit(idt);
4904 if (sx) *it=sx->GetSignal("index1");
4905 }
4906 }
4907 }
4908 return da;
4909}
4910
4911Double_t NcAstrolab::GetSeparation(TString name1,TString name2,TString au,Double_t* dt,TString tu,Int_t mode,Double_t* diftheta,Double_t* difphi)
4912{
4959
4960 // Obtain the storage indices for the requested signals
4961 Int_t i=GetSignalIndex(name1,1); // Search for "name1" among the measurement signals
4962 Int_t j=GetSignalIndex(name2,1); // Search for "name2" among the measurement signals
4963
4964 if (i>0) // Set to negative value to indicate measurement entry
4965 {
4966 i=-i;
4967 }
4968 else // Search for "name1" among the reference signals
4969 {
4970 // In case a Solar system body was specified, store c.q. update it as a reference object.
4971 SetSolarSystem(name1,0,0);
4972 i=GetSignalIndex(name1,0);
4973 if (i<0) i=0;
4974 }
4975
4976 if (j>0) // Set to negative value to indicate measurement entry
4977 {
4978 j=-j;
4979 }
4980 else // Search for "name2" among the reference signals
4981 {
4982 // In case a Solar system body was specified, store c.q. update it as a reference object.
4983 SetSolarSystem(name2,0,0);
4984 j=GetSignalIndex(name2,0);
4985 if (j<0) j=0;
4986 }
4987
4988 // Retrieve the requested data via the internal GetSeparation() memberfunction
4989 Double_t dtx;
4990 Double_t da=GetSeparation(i,j,au,dtx,tu,mode,0,diftheta,difphi);
4991
4992Double_t dthetax,dphix;
4993da=GetSeparation(i,j,au,dtx,tu,mode,0,&dthetax,&dphix);
4994printf(" i=%-i j=%-i da=%-g dt=%-g %-s dtheta=%-g dphi=%-g %-s \n",i,j,da,dtx,tu.Data(),dthetax,dphix,au.Data());
4995
4996 if (dt) *dt=dtx;
4997 return da;
4998}
4999
5000Double_t NcAstrolab::GetSeparation(Int_t i,Int_t j,TString au,Double_t& dt,TString tu,Int_t mode,Int_t bkgpatch,Double_t* diftheta,Double_t* difphi)
5001{
5049
5050 Double_t dang=-999;
5051 dt=1.e30;
5052 if (diftheta) *diftheta=-999;
5053 if (difphi) *difphi=-999;
5054
5055 if (!i || !j) return dang;
5056 if ((i>0 || j>0) && !fRefs) return dang;
5057 if ((i<0 || j<0) && !fSigs) return dang;
5058
5059 // If needed, initialise the randomiser with a "date/time driven" seed
5060 // using the timestamp of the moment of this invokation of the member function.
5061 // This will ensure different random sequences if the user repeats analyses
5062 // with identical measurements and reference signals without explicit initialisation
5063 // of the randomiser by the user at the start of the analysis.
5064 if (!fRan && (fRscmode>0 || fTscmode>0)) fRan=new NcRandom(-1);
5065
5066 Int_t itype=0;
5067 if (i<0)
5068 {
5069 itype=1;
5070 i=abs(i);
5071 }
5072
5073 Int_t jtype=0;
5074 if (j<0)
5075 {
5076 jtype=1;
5077 j=abs(j);
5078 }
5079
5080 Nc3Vector ri; // Position of the i-th signal
5081 Nc3Vector rj; // Position of the j-th signal
5082 NcSignal* si=0; // Link to the stored i-th signal
5083 NcSignal* sj=0; // Link to the stored j-th signal
5084 NcTimestamp* ti=0; // Link to the timestamp of the i-th signal
5085 NcTimestamp* tj=0; // Link to the timestamp of the j-th signal
5086
5087 si=GetSignal(i,itype);
5088 sj=GetSignal(j,jtype);
5089 if (!si || !sj) return dang;
5090
5091 ti=si->GetTimestamp();
5092 tj=sj->GetTimestamp();
5093 if (!ti || !tj) return dang;
5094
5095 Int_t reftype=0;
5096 Int_t evttype=0;
5097 Int_t idxref=0;
5098 Int_t idxevt=0;
5099 NcSignal* sxref=0; // Link to the stored reference signal
5100 NcTimestamp* txref=0; // Link to the timestamp of the reference signal
5101 NcTimestamp* txevt=0; // Link to the timestamp of the measurement signal
5102 Nc3Vector rxref; // Position of the reference signal
5103 Nc3Vector rxevt; // Position of the measurement signal
5104
5105 if (itype==jtype) // Self correlations
5106 {
5107 reftype=itype;
5108 idxref=i;
5109 sxref=si;
5110 txref=ti;
5111 evttype=jtype;
5112 idxevt=j;
5113 txevt=tj;
5114 }
5115 else // Correlations between sources and measurements
5116 {
5117 if (itype)
5118 {
5119 evttype=itype;
5120 idxevt=i;
5121 txevt=ti;
5122 reftype=jtype;
5123 idxref=j;
5124 sxref=sj;
5125 txref=tj;
5126 }
5127 else
5128 {
5129 reftype=itype;
5130 idxref=i;
5131 sxref=si;
5132 txref=ti;
5133 evttype=jtype;
5134 idxevt=j;
5135 txevt=tj;
5136 }
5137 }
5138
5139 // Update the location and timestamp in case of a Solar system reference object
5140 TString name=sxref->GetName();
5141 if (SetSolarSystem(name,txevt,reftype)) txref=sxref->GetTimestamp();
5142
5143 // Local variables to act on requested scrambling
5144 Int_t Tscmode=fTscmode;
5145 Int_t Rscmode=fRscmode;
5146
5147 // Create scrambled background patch data even when also the on-source data are scrambled
5148 if (bkgpatch)
5149 {
5150 Tscmode=-abs(fTscmode);
5151 Rscmode=-abs(fRscmode);
5152 }
5153
5154 // Apply time scrambling of the date/time of the observation if requested
5155 NcTimestamp txtmp(*txevt);
5156 Double_t trndm=0;
5157 if (Tscmode==1 || Tscmode==3 || (Tscmode<0 && bkgpatch))
5158 {
5159 if (!fTscfunc)
5160 {
5161 trndm=fRan->Uniform(fTscmin,fTscmax);
5162 }
5163 else
5164 {
5165 trndm=fTscfunc->GetRandom(fTscmin,fTscmax);
5166 }
5167 // Creating a fake scrambled timestamp
5168 if (Tscmode==3 || (abs(Tscmode)>1 && bkgpatch)) txtmp.AddSec(trndm);
5169 }
5170
5171 // Obtain the (scrambled) time difference
5172 if (Tscmode==1 || (Tscmode==-1 && bkgpatch)) // Only provide a random time difference
5173 {
5174 if (tu=="d")
5175 {
5176 trndm/=double(24*3600);
5177 }
5178 if (tu=="ns")
5179 {
5180 trndm*=1.e9;
5181 trndm*=1.e9;
5182 }
5183 if (tu=="ps")
5184 {
5185 trndm*=1.e12;
5186 trndm*=1.e12;
5187 }
5188 dt=trndm;
5189 }
5190 else // Determine the time difference w.r.t. the fake timestamp of the measurement
5191 {
5192 dt=txref->GetDifference(&txtmp,tu,mode);
5193 }
5194
5195 // Update the location of Solar system objects if needed
5196 name=sxref->GetName();
5197 SetSolarSystem(name,&txtmp,reftype);
5198
5199 // Get the original measurement position and (time modified) reference position in local coordinates
5200 GetSignal(rxevt,"loc","T",txevt,idxevt,evttype);
5201 GetSignal(rxref,"loc","T",&txtmp,idxref,reftype);
5202
5203 // Apply position scrambling of the measurement if requested
5204 Double_t pi=acos(-1.);
5205 Float_t cosmin=0;
5206 Float_t cosmax=0;
5207 Double_t cosang=0;
5208 Double_t vec[3];
5209 Double_t dd=0;
5210 Double_t dtheta=0;
5211 Double_t dphi=0;
5212
5213 if (Rscmode==1 || (Rscmode==-1 && bkgpatch)) // Only provide a random angular separation
5214 {
5215 if (!fDscfunc)
5216 {
5217 cosmin=cos(fDscmin*pi/180.);
5218 cosmax=cos(fDscmax*pi/180.);
5219 if (cosmin>cosmax)
5220 {
5221 Float_t temp=cosmin;
5222 cosmin=cosmax;
5223 cosmax=temp;
5224 }
5225 cosang=fRan->Uniform(cosmin,cosmax);
5226 dang=acos(cosang);
5227 if (au=="deg") dang*=180./pi;
5228 }
5229 else
5230 {
5231 dang=fDscfunc->GetRandom(fDscmin,fDscmax);
5232 if (au=="rad") dang*=pi/180.;
5233 }
5234 }
5235 else // Create a fake local position for the measurement
5236 {
5237 if (Rscmode==3 || (abs(Rscmode)>1 && bkgpatch))
5238 {
5239 rxevt.GetVector(vec,"sph","deg");
5240
5241 // Allow specific offset studies
5242 if (fDscmin==fDscmax) dd=fDscmin;
5243 if (fThetascmin==fThetascmax) dtheta=fThetascmin;
5244 if (fPhiscmin==fPhiscmax) dphi=fPhiscmin;
5245
5246 // Go for randomly scrambled values
5247 if (fDscfunc)
5248 {
5249 if (fDscmax>fDscmin)
5250 {
5251 dd=fDscfunc->GetRandom(fDscmin,fDscmax);
5252 }
5253 }
5254 else
5255 {
5256 if (fDscmax>fDscmin) dd=fRan->Uniform(fDscmin,fDscmax);
5257 }
5258
5259 if (fThetascfunc)
5260 {
5262 {
5263 dtheta=fThetascfunc->GetRandom(fThetascmin,fThetascmax);
5264 }
5265 }
5266 else if (fThetascmax>fThetascmin)
5267 {
5268 cosmin=cos(fThetascmin*pi/180.);
5269 cosmax=cos(fThetascmax*pi/180.);
5270 if (cosmin>cosmax)
5271 {
5272 Float_t temp=cosmin;
5273 cosmin=cosmax;
5274 cosmax=temp;
5275 }
5276 cosang=fRan->Uniform(cosmin,cosmax);
5277 dtheta=acos(cosang)*180./pi;
5278 }
5279
5280 if (fPhiscfunc)
5281 {
5282 if (fPhiscmax>fPhiscmin)
5283 {
5284 dphi=fPhiscfunc->GetRandom(fPhiscmin,fPhiscmax);
5285 }
5286 }
5287 else
5288 {
5289 if (fPhiscmax>fPhiscmin) dphi=fRan->Uniform(fPhiscmin,fPhiscmax);
5290 }
5291
5292 vec[0]+=dd;
5293 if (vec[0]<=0) vec[0]=1e-20; // Keep a physical situation
5294 vec[1]+=dtheta;
5295 vec[2]+=dphi;
5296 rxevt.SetVector(vec,"sph","deg");
5297 }
5298
5299 dang=rxref.GetOpeningAngle(rxevt,au);
5300 }
5301
5302 // Determine the difference in local theta and phi
5303 Double_t refvec[3];
5304 rxevt.GetVector(vec,"sph",au);
5305 rxref.GetVector(refvec,"sph",au);
5306 dtheta=vec[1]-refvec[1];
5307 dphi=vec[2]-refvec[2];
5308 if (diftheta) *diftheta=dtheta;
5309 if (difphi) *difphi=dphi;
5310
5311 return dang;
5312}
5313
5314Double_t NcAstrolab::GetDifference(TString name,TString au,Double_t& dt,TString tu,Int_t mode)
5315{
5350
5351 Double_t dang=999;
5352 dt=1.e30;
5353
5354 Int_t j=GetSignalIndex(name);
5355
5356 if (j==-1) // Set and store info for the requested Solar system object if not already stored
5357 {
5358 SetSolarSystem(name,0);
5359 j=GetSignalIndex(name);
5360 }
5361
5362 if (j>0) dang=GetDifference(j,au,dt,tu,mode);
5363 return dang;
5364}
5365
5366TArrayI* NcAstrolab::MatchRefSignal(Double_t da,TString au,Double_t dt,TString tu,Int_t mode)
5367{
5396
5397 if (!fSigs || !fRefs) return 0;
5398
5399 NcDevice matches;
5400 MatchSignals(matches,da,au,dt,tu,mode,1,0,0,1,1,1); // Perform the obsolete MatchRefSignal() action
5401
5402 Int_t nhits=matches.GetNhits();
5403 if (!nhits) return 0;
5404
5405 if (fIndices) delete fIndices;
5406 fIndices=new TArrayI(nhits);
5407
5408 Int_t index=0;
5409 NcSignal* sx=0;
5410 Int_t jfill=0;
5411 for (Int_t i=1; i<=nhits; i++)
5412 {
5413 sx=matches.GetHit(i);
5414
5415 if(!sx) continue;
5416
5417 index=sx->GetSignal("index1");
5418 fIndices->AddAt(index,jfill);
5419 jfill++;
5420 }
5421
5422 fIndices->Set(jfill);
5423
5424 if (!jfill) return 0; // No match found
5425
5426 return fIndices;
5427}
5428
5429void NcAstrolab::MatchSignals(NcDevice& matches,Double_t da,TString au,Double_t dt,TString tu,Int_t mode,Int_t i1,Int_t i2,Int_t itype,Int_t j1,Int_t j2,Int_t jtype)
5430{
5542
5543 // Initialize the Device/Hit structure to contain the correlation info
5544 matches.Reset(1);
5545 matches.SetHitCopy(1);
5546
5547 TString name="Matches";
5548 TString title="Space and time matchings of NcAstrolab stored signals";
5549 matches.SetNameTitle(name.Data(),title.Data());
5550 TString tux=tu;
5551 if (tu=="d") tux="days";
5552 if (tu=="s") tux="sec";
5553 TString namedamin="psimin in ";
5554 namedamin+=au;
5555 TString namedtmin="dtmin in ";
5556 namedtmin+=tux;
5557 matches.AddNamedSlot(namedamin);
5558 matches.AddNamedSlot(namedtmin);
5559 matches.AddNamedSlot("ipsi");
5560 matches.AddNamedSlot("idt");
5561
5562 NcSignal data;
5563 TString nameda="psi in ";
5564 nameda+=au;
5565 TString namedt="t2-t1 in ";
5566 namedt+=tux;
5567 data.AddNamedSlot("type1");
5568 data.AddNamedSlot("index1");
5569 data.AddNamedSlot("type2");
5570 data.AddNamedSlot("index2");
5571 data.AddNamedSlot(nameda);
5572 data.AddNamedSlot(namedt);
5573
5574 if ((!itype || !jtype) && !fRefs)
5575 {
5576 printf(" *%-s::MatchSignals* Error: itype=%-i jtype=%-i but no reference signals are present. \n",ClassName(),itype,jtype);
5577 return;
5578 }
5579
5580 if ((itype || jtype) && !fSigs)
5581 {
5582 printf(" *%-s::MatchSignals* Error: itype=%-i jtype=%-i but no measurements are present. \n",ClassName(),itype,jtype);
5583 return;
5584 }
5585
5586 Int_t nrefs=0;
5587 if (fRefs) nrefs=fRefs->GetSize();
5588 Int_t nsigs=0;
5589 if (fSigs) nsigs=fSigs->GetSize();
5590
5591
5592 // Make input data consistent with conventions
5593 if (itype) itype=1;
5594 if (jtype) jtype=1;
5595 if (!itype)
5596 {
5597 if (i2<1 || i2>nrefs) i2=nrefs;
5598 }
5599 else
5600 {
5601 if (i2<1 || i2>nsigs) i2=nsigs;
5602 }
5603 if (!jtype)
5604 {
5605 if (j2<1 || j2>nrefs) j2=nrefs;
5606 }
5607 else
5608 {
5609 if (j2<1 || j2>nsigs) j2=nsigs;
5610 }
5611
5612 if (i1<1 || j1<1 || i1>i2 || j1>j2)
5613 {
5614 printf(" *%-s::MatchSignals* Inconsistent parameters: i1=%-i i2=%-i itype=%-i j1=%-i j2=%-i jtype=%-i. \n",ClassName(),i1,i2,itype,j1,j2,jtype);
5615 return;
5616 }
5617
5618 Double_t dang,dtime;
5619 Int_t ix=0;
5620 Int_t jx=0;
5621 NcSignal* sx=0;
5622 Int_t id=0;
5623 Double_t dangmin=0;
5624 Double_t dtmin=0;
5625 Int_t idamin=0;
5626 Int_t idtmin=0;
5627 Bool_t first=kTRUE;
5628 for (Int_t i=i1; i<=i2; i++)
5629 {
5630 ix=i;
5631 if (itype) ix=-i;
5632
5633 for (Int_t j=j1; j<=j2; j++)
5634 {
5635 // Skip matching a signal with itself
5636 if (itype==jtype && i==j) continue;
5637
5638 jx=j;
5639 if (jtype) jx=-j;
5640
5641 dang=GetSeparation(ix,jx,au,dtime,tu,mode,0);
5642
5643 if ((fabs(dang)<=da || da<0) && (fabs(dtime)<=dt || dt<0))
5644 {
5645 data.Reset();
5646 name="Object1=";
5647 sx=GetSignal(i,itype);
5648 if (!sx) continue;
5649 name+=sx->GetName();
5650 title="Object2=";
5651 sx=GetSignal(j,jtype);
5652 if (!sx) continue;
5653 title+=sx->GetName();
5654 id++;
5655 data.SetNameTitle(name.Data(),title.Data());
5656 data.SetUniqueID(id);
5657 data.SetSignal(itype,"type1");
5658 data.SetSignal(i,"index1");
5659 data.SetSignal(jtype,"type2");
5660 data.SetSignal(j,"index2");
5661 data.SetSignal(dtime,namedt);
5662 data.SetSignal(dang,nameda);
5663 matches.AddHit(data);
5664
5665 // Record the data for the minimal encountered opening angle
5666 if (first || fabs(dang)<dangmin)
5667 {
5668 dangmin=fabs(dang);
5669 idamin=id;
5670 }
5671
5672 // Record the data for the minimal encountered time difference
5673 if (first || fabs(dtime)<fabs(dtmin))
5674 {
5675 dtmin=dtime;
5676 idtmin=id;
5677 }
5678
5679 first=kFALSE;
5680 }
5681 }
5682 }
5683
5684 // Store the data for the minimal encountered opening angle and time difference
5685 matches.SetSignal(dangmin,namedamin);
5686 matches.SetSignal(dtmin,namedtmin);
5687 matches.SetSignal(idamin,"ipsi");
5688 matches.SetSignal(idtmin,"idt");
5689}
5690
5691void NcAstrolab::MatchSignals(NcDevice& matches,TString name,Double_t da,TString au,Double_t dt,TString tu,Int_t mode,Int_t itype,Int_t j1,Int_t j2,Int_t jtype)
5692{
5802
5803 Int_t i=GetSignalIndex(name,itype);
5804
5805 if (i==-1) // Add the info for the requested Solar system object if not already stored
5806 {
5807 SetSolarSystem(name,0,itype);
5808 i=GetSignalIndex(name,itype);
5809 if (i>0) fSolUpdate=1;
5810 }
5811
5812 if (i<1)
5813 {
5814 printf(" *%-s::MatchSignals* Object %-s not found for itype=%-i. \n",ClassName(),name.Data(),itype);
5815 }
5816 else
5817 {
5818 MatchSignals(matches,da,au,dt,tu,mode,i,i,itype,j1,j2,jtype);
5819 }
5820
5821 fSolUpdate=0;
5822}
5823
5824void NcAstrolab::SetTimeScramble(Int_t mode,Double_t tmin,Double_t tmax,TF1* frndm)
5825{
5895
5896 fTscmode=mode;
5897 fTscmin=tmin;
5898 fTscmax=tmax;
5899 if (fTscfunc)
5900 {
5901 delete fTscfunc;
5902 fTscfunc=0;
5903 }
5904 if (frndm)
5905 {
5906 fTscfunc=new TF1(*frndm);
5907 if (tmax>tmin) fTscfunc->SetRange(tmin,tmax);
5908 }
5909}
5910
5911Int_t NcAstrolab::GetTimeScramble(Double_t* tmin,Double_t* tmax,TF1* frndm)
5912{
5942
5943 if (tmin) *tmin=fTscmin;
5944 if (tmax) *tmax=fTscmax;
5945 if (frndm) *frndm=*fTscfunc;
5946
5947 return fTscmode;
5948}
5949
5950void NcAstrolab::SetPositionScramble(Int_t mode,Double_t dmin,Double_t dmax,TF1* df,Double_t thmin,Double_t thmax,TF1* thf,Double_t phimin,Double_t phimax,TF1* phif)
5951{
6029
6030 // Keep parameters within physical bounds for angular difference scrambling (mode=1)
6031 if (abs(mode)==1 && dmin<0) dmin=0;
6032 if (abs(mode)==1 && dmax>180) dmax=180;
6033
6034 // Check for specific requested offsets
6035 if (dmax<dmin) dmax=dmin;
6036 if (thmax<thmin) thmax=thmin;
6037 if (phimax<phimin) phimax=phimin;
6038
6039 fRscmode=mode;
6040 fDscmin=dmin;
6041 fDscmax=dmax;
6042 if (fDscfunc)
6043 {
6044 delete fDscfunc;
6045 fDscfunc=0;
6046 }
6047 if (df)
6048 {
6049 fDscfunc=new TF1(*df);
6050 if (dmax>dmin) fDscfunc->SetRange(dmin,dmax);
6051 }
6052 fThetascmin=thmin;
6053 fThetascmax=thmax;
6054 if (fThetascfunc)
6055 {
6056 delete fThetascfunc;
6057 fThetascfunc=0;
6058 }
6059 if (thf)
6060 {
6061 fThetascfunc=new TF1(*thf);
6062 if (thmax>thmin) fThetascfunc->SetRange(thmin,thmax);
6063 }
6064 fPhiscmin=phimin;
6065 fPhiscmax=phimax;
6066 if (fPhiscfunc)
6067 {
6068 delete fPhiscfunc;
6069 fPhiscfunc=0;
6070 }
6071 if (phif)
6072 {
6073 fPhiscfunc=new TF1(*phif);
6074 if (phimax>phimin) fPhiscfunc->SetRange(phimin,phimax);
6075 }
6076}
6077
6078Int_t NcAstrolab::GetPositionScramble(Double_t* dmin,Double_t* dmax,TF1* df,Double_t* thmin,Double_t* thmax,TF1* thf,Double_t* phimin,Double_t* phimax,TF1* phif)
6079{
6115
6116 if (dmin) *dmin=fDscmin;
6117 if (dmax) *dmax=fDscmax;
6118 if (df) *df=*fDscfunc;
6119 if (thmin) *thmin=fThetascmin;
6120 if (thmax) *thmax=fThetascmax;
6121 if (thf) *thf=*fThetascfunc;
6122 if (phimin) *phimin=fPhiscmin;
6123 if (phimax) *phimax=fPhiscmax;
6124 if (phif) *phif=*fPhiscfunc;
6125
6126 return fRscmode;
6127}
6128
6129void NcAstrolab::DisplaySignal(TString frame,TString mode,NcTimestamp* ts,Int_t j,TString proj,Int_t clr,TString name)
6130{
6229
6230 // Comply with the new (jref,type) convention for measurements and reference signals.
6231 Int_t jref=abs(j);
6232 Int_t type=0;
6233 if (j<=0) type=1;
6234 if (!j) jref=1;
6235
6236 NcSignal* sx=0;
6237
6238 if (!ts)
6239 {
6240 sx=GetSignal(jref,type);
6241 if (!sx) return;
6242 ts=sx->GetTimestamp();
6243 }
6244
6245 Nc3Vector r;
6246 sx=GetSignal(r,frame,mode,ts,jref,type);
6247
6248 if (!sx) return;
6249
6250 // Save name and timestamp to enable timestamp restoration for Solar system objects
6251 // after a Day View or Year View display
6252 TString namesave=sx->GetName();
6253 NcTimestamp tsave=(*ts);
6254
6255 // The generic input angles (in rad) for the projections
6256 Double_t theta=0;
6257 Double_t phi=0;
6258
6259 Double_t pi=acos(-1.);
6260
6261 if (frame=="equ" || frame=="gal" || frame=="icr" || frame=="ecl" || frame=="loc")
6262 {
6263 theta=(pi/2.)-r.GetX(2,"sph","rad");
6264 phi=r.GetX(3,"sph","rad");
6265 }
6266
6267 if (frame=="hor")
6268 {
6269 theta=(pi/2.)-r.GetX(2,"sph","rad");
6270 phi=pi-r.GetX(3,"sph","rad");
6271 }
6272
6273 // Automatic choice of central meridian if not selected by the user
6274 if (!fUsMeridian || abs(fUsMeridian)>1)
6275 {
6276 if (frame=="equ")
6277 {
6278 fMeridian=pi;
6279 fUsMeridian=-2;
6280 }
6281 if (frame=="gal" || frame=="icr" || frame=="ecl")
6282 {
6283 fMeridian=0;
6284 fUsMeridian=-2;
6285 }
6286 if (frame=="hor" || frame=="loc")
6287 {
6288 fMeridian=0;
6289 fUsMeridian=2;
6290 }
6291 }
6292
6293 // Obtain the projected (x,y) position
6294 Double_t x=0;
6295 Double_t y=0;
6296 Project(phi,theta,proj,x,y);
6297
6298 // X-axis inversion of the display
6299 if (fUsMeridian<0) x*=-1.;
6300
6301 Int_t hist=0;
6302 if (proj=="hamh" || proj=="aith" || proj=="merh" || proj=="cylh" || proj=="angh") hist=1;
6303 if (proj=="UTh" || proj=="LTh" || proj=="GSTh" || proj=="LSTh") hist=1;
6304 if (proj=="UYh" || proj=="LYh" || proj=="GSYh" || proj=="LSYh") hist=1;
6305
6306 // Update the display for this signal position
6307
6308 // Create a new canvas if needed
6309 if (!fCanvas || !(gROOT->GetListOfCanvases()->FindObject("NcAstrolab"))) fCanvas=new TCanvas("NcAstrolab","Skymap");
6310
6311 // Construct the various strings for this map
6312 TString titleup; // The upper title string
6313 TString titlelow; // The lower title string
6314 TString sleft; // The most left coordinate indicator
6315 TString sright; // The most right coordinate indicator
6316 TString sup; // The most upper coordinate indicator
6317 TString slow; // The most lower coordinate indicator
6318 sup="90#circ";
6319 slow="-90#circ";
6320 if (name!="")
6321 {
6322 titleup=name;
6323 titleup+=" ";
6324 }
6325 if (frame=="equ")
6326 {
6327 titleup+="Geocentric Equatorial (";
6328 titleup+=mode;
6329 if (mode=="J") titleup+="2000";
6330 if (mode=="B") titleup+="1950";
6331 titleup+=") ";
6332 }
6333 if (frame=="gal") titleup+="Heliocentric Galactic";
6334 if (frame=="ecl") titleup+=" Geocentric Ecliptic";
6335 if (frame=="hor") titleup+=" Standard Horizon";
6336 if (frame=="icr") titleup+="Static Barycentric ICRS";
6337 if (frame=="loc")
6338 {
6339 titleup+=" User defined Local";
6340 sup=" 0#circ";
6341 slow="180#circ";
6342 }
6343 titleup+=" Coordinates";
6344 titlelow="Projection : ";
6345 if (proj=="ham" || proj=="hamh") titlelow+="Hammer";
6346 if (proj=="cyl" || proj=="cylh") titlelow+="Cylindrical";
6347 if (proj=="ait" || proj=="aith") titlelow+="Aitoff";
6348 if (proj=="mer" || proj=="merh") titlelow+="Mercator";
6349 if (proj=="ang" || proj=="angh")
6350 {
6351 titlelow+="sin(b) vs. l";
6352 sup=" 1";
6353 slow=" -1";
6354 }
6355 titlelow+=" Central Meridian : ";
6356 Int_t ang,h,m,s,d;
6357 Int_t angmax,hmin,hmax,dmin,dmax;
6358 TString corr;
6359 TString scenter="";
6360 if (frame=="equ")
6361 {
6362 ang=int(ConvertAngle(fMeridian,"rad","hms"));
6363 angmax=ang+120000;
6364 h=ang/10000;
6365 ang=ang%10000;
6366 m=ang/100;
6367 s=ang%100;
6368 titlelow+=h;
6369 titlelow+="h ";
6370 titlelow+=m;
6371 titlelow+="m ";
6372 titlelow+=s;
6373 titlelow+="s";
6374 hmax=angmax/10000;
6375 corr="";
6376 while (hmax>24)
6377 {
6378 hmax-=24;
6379 corr="+";
6380 }
6381 hmin=hmax-24;
6382 while (hmin<-12)
6383 {
6384 hmin+=24;
6385 corr="+";
6386 }
6387 sright+=corr;
6388 if (fUsMeridian<0)
6389 {
6390 sright+=hmin;
6391 }
6392 else
6393 {
6394 sright+=hmax;
6395 }
6396 sright+="h";
6397 if (fUsMeridian<0)
6398 {
6399 sleft+=hmax;
6400 }
6401 else
6402 {
6403 sleft+=hmin;
6404 }
6405 sleft+="h";
6406 scenter+=h;
6407 scenter+="h";
6408 }
6409 else
6410 {
6411 ang=int(ConvertAngle(fMeridian,"rad","dms"));
6412 angmax=ang+1800000;
6413 d=ang/10000;
6414 ang=ang%10000;
6415 m=ang/100;
6416 s=ang%100;
6417 titlelow+=d;
6418 titlelow+="d ";
6419 titlelow+=m;
6420 titlelow+="' ";
6421 titlelow+=s;
6422 titlelow+="\"";
6423 dmax=angmax/10000;
6424 corr="";
6425 while (dmax>360)
6426 {
6427 dmax-=360;
6428 corr="+";
6429 }
6430 dmin=dmax-360;
6431 while (dmin<-180)
6432 {
6433 dmin+=360;
6434 corr="+";
6435 }
6436 sright+=corr;
6437 if (fUsMeridian<0)
6438 {
6439 sright+=dmin;
6440 }
6441 else
6442 {
6443 sright+=dmax;
6444 }
6445 sright+="#circ";
6446 if (fUsMeridian<0)
6447 {
6448 sleft+=dmax;
6449 }
6450 else
6451 {
6452 sleft+=dmin;
6453 }
6454 sleft+="#circ";
6455 scenter+=d;
6456 scenter+="#circ";
6457 }
6458
6459 if (!hist) // 2-D Marker display (i.e. not a histogram)
6460 {
6461 TMarker* marker=0;
6462 // Remove existing markers, grid and outline from display if needed
6463 if (clr==1 || proj!=fProj)
6464 {
6465 if (fMarkers)
6466 {
6467 delete fMarkers;
6468 fMarkers=0;
6469 }
6470 fCanvas->Clear();
6471 fProj=proj;
6472 }
6473
6474 // Create a new display if needed
6475 if (!fMarkers)
6476 {
6477 fMarkers=new TObjArray();
6478 fMarkers->SetOwner();
6479
6480 // Set canvas range, header and axes
6481 Float_t xup=2; // Maximal x coordinate of the projection
6482 Float_t yup=1; // maximal y coordinate of the projection
6483 Float_t xlow=-xup;
6484 Float_t ylow=-yup;
6485 Float_t xmargin=0.5; // X margin for canvas size
6486 Float_t ymargin=0.3; // Y margin for canvas size
6487 fCanvas->Range(xlow-xmargin,ylow-ymargin,xup+xmargin,yup+ymargin);
6488
6489 // The ellipse outline with the skymap c.q. projection grid
6490 if (proj=="ham" || proj=="ait")
6491 {
6492 // Draw ellips outline
6493 TEllipse* outline=new TEllipse(0,0,xup,yup);
6494 fMarkers->Add(outline);
6495 outline->Draw();
6496 }
6497
6499 // Draw the skymap c.q. projection grid //
6501
6502 // Drawing of the projected meridians every 30 degrees
6503 const Int_t nphi=13;
6504 Double_t gphiarr[nphi]={0,30,60,90,120,150,180,210,240,270,300,330,360};
6505 Double_t gphi=0;
6506 Double_t gtheta=0;
6507 Int_t ndots=100;
6508 Float_t gstep=180./float(ndots);
6509 Double_t xgrid=0;
6510 Double_t ygrid=0;
6511 for (Int_t iph=0; iph<nphi; iph++)
6512 {
6513 gphi=gphiarr[iph]*pi/180.;
6514 if (frame=="hor") gphi=pi-gphi;
6515 gtheta=pi/2.;
6516 for (Int_t ith=1; ith<ndots; ith++)
6517 {
6518 gtheta=gtheta-(gstep*pi/180.);
6519 Project(gphi,gtheta,proj,xgrid,ygrid);
6520 marker=new TMarker(xgrid,ygrid,fMarkerStyle[3]);
6521 marker->SetMarkerSize(fMarkerSize[3]);
6522 marker->SetMarkerColor(fMarkerColor[3]);
6523 fMarkers->Add(marker);
6524 marker->Draw();
6525 }
6526 }
6527
6528 // Drawing of the projected latitude circles every 15 degrees
6529 const Int_t nth=10;
6530 Double_t gtharr[nth]={15,30,45,60,75,105,120,135,150,165};
6531 gphi=0;
6532 gtheta=0;
6533 gstep=360./float(ndots);
6534 TString gs;
6535 Int_t igs=0;
6536 TLatex* lgs=0;
6537 Double_t xtext=0;
6538 Double_t ytext=0;
6539 for (Int_t ith=0; ith<nth; ith++)
6540 {
6541 gtheta=pi/2.-(gtharr[ith]*pi/180.);
6542 igs=int(90.-gtharr[ith]);
6543 if (frame=="loc") igs=int(gtharr[ith]);
6544 gs="";
6545 gs+=igs;
6546 gs+="#circ";
6547 xtext=0;
6548 for (Int_t iphi=1; iphi<ndots; iphi++)
6549 {
6550 gphi=gphi+gstep;
6551 Project(gphi,gtheta,proj,xgrid,ygrid);
6552 marker=new TMarker(xgrid,ygrid,fMarkerStyle[3]);
6553 marker->SetMarkerSize(fMarkerSize[3]);
6554 marker->SetMarkerColor(fMarkerColor[3]);
6555 if (xgrid<xtext)
6556 {
6557 xtext=xgrid;
6558 ytext=ygrid;
6559 }
6560 fMarkers->Add(marker);
6561 marker->Draw();
6562 }
6563 lgs=new TLatex;
6564 fMarkers->Add(lgs);
6565 if (ytext>0)
6566 {
6567 if (proj=="ham" || proj=="ait")
6568 {
6569 lgs->DrawLatex(xtext-0.25,ytext,gs.Data());
6570 }
6571 else
6572 {
6573 lgs->DrawLatex(xtext-0.4,ytext-0.02,gs.Data());
6574 }
6575 }
6576 else
6577 {
6578 if (proj=="ham" || proj=="ait")
6579 {
6580 lgs->DrawLatex(xtext-0.3,ytext-0.1,gs.Data());
6581 }
6582 else
6583 {
6584 lgs->DrawLatex(xtext-0.4,ytext-0.02,gs.Data());
6585 }
6586 }
6587 }
6588
6589 // The horizontal and vertical axes
6590 TLine* line=new TLine(xlow,0,xup,0);
6591 fMarkers->Add(line);
6592 line->Draw();
6593 line=new TLine(0,yup,0,ylow);
6594 fMarkers->Add(line);
6595 line->Draw();
6596
6597 // The header and footer text
6598 TLatex* header=new TLatex;
6599 fMarkers->Add(header);
6600 header->SetTextAlign(21); // Text will be horizontally centered
6601 header->DrawLatex(0,yup+0.2,titleup.Data());
6602 TLatex* footer=new TLatex;
6603 fMarkers->Add(footer);
6604 footer->SetTextAlign(21); // Text will be horizontally centered
6605 footer->DrawLatex(0,ylow-0.25,titlelow.Data());
6606
6607 // The left side angular value indicator
6608 TLatex* left=new TLatex;
6609 fMarkers->Add(left);
6610 if (proj=="ham" || proj=="ait")
6611 {
6612 left->DrawLatex(xlow-0.4,0,sleft.Data());
6613 }
6614 else
6615 {
6616 left->DrawLatex(xlow-0.15,yup+0.05,sleft.Data());
6617 }
6618 // The right side angular value indicator
6619 TLatex* right=new TLatex;
6620 fMarkers->Add(right);
6621 if (proj=="ham" || proj=="ait")
6622 {
6623 right->DrawLatex(xup+0.1,0,sright.Data());
6624 }
6625 else
6626 {
6627 right->DrawLatex(xup-0.1,yup+0.05,sright.Data());
6628 }
6629 // The upper angular value indicator
6630 TLatex* up=new TLatex;
6631 fMarkers->Add(up);
6632 if (proj=="ham" || proj=="ait")
6633 {
6634 up->DrawLatex(-0.1,yup+0.05,sup.Data());
6635 }
6636 else
6637 {
6638 up->DrawLatex(-0.1,yup+0.05,scenter.Data());
6639 if (proj!="ang")
6640 {
6641 up=new TLatex;
6642 fMarkers->Add(up);
6643 up->DrawLatex(xlow-0.4,yup-0.04,sup.Data());
6644 }
6645 }
6646 // The lower angular value indicator
6647 TLatex* low=new TLatex;
6648 fMarkers->Add(low);
6649 if (proj=="ham" || proj=="ait")
6650 {
6651 low->DrawLatex(-0.15,ylow-0.15,slow.Data());
6652 }
6653 else
6654 {
6655 if (proj!="ang") low->DrawLatex(xlow-0.4,ylow,slow.Data());
6656 }
6657
6659 // Indicate the Galactic Center //
6661
6662 // Add the Galactic Center temporarily as a reference signal for coordinate retrieval
6663 sx=SetSignal(1,0,"deg",0,"deg","gal",0,-1,"J","GC",0);
6664 Int_t idx=fRefs->IndexOf(sx);
6665 idx++;
6666 Nc3Vector rgc;
6667 sx=GetSignal(rgc,frame,mode,ts,idx,0);
6668 if (sx)
6669 {
6670 Double_t thetagc=0;
6671 Double_t phigc=0;
6672 if (frame=="equ" || frame=="gal" || frame=="icr" || frame=="ecl" || frame=="loc")
6673 {
6674 thetagc=(pi/2.)-rgc.GetX(2,"sph","rad");
6675 phigc=rgc.GetX(3,"sph","rad");
6676 }
6677 if (frame=="hor")
6678 {
6679 thetagc=(pi/2.)-rgc.GetX(2,"sph","rad");
6680 phigc=pi-rgc.GetX(3,"sph","rad");
6681 }
6682 // Obtain the projected (x,y) position
6683 Double_t xgc=0;
6684 Double_t ygc=0;
6685 Project(phigc,thetagc,proj,xgc,ygc);
6686 if (fUsMeridian<0) xgc*=-1.;
6687 marker=new TMarker(xgc,ygc,fMarkerStyle[2]);
6688 marker->SetMarkerSize(fMarkerSize[2]);
6689 marker->SetMarkerColor(fMarkerColor[2]);
6690 fMarkers->Add(marker);
6691 marker->Draw();
6692 // Remove the temporary Galactic Center object again
6693 RemoveSignal(idx,0,0);
6694 }
6695 }
6696
6697 // Indicate the measurement(s) or reference signal(s) on the display
6698 marker=new TMarker(x,y,fMarkerStyle[type]);
6699 marker->SetMarkerSize(fMarkerSize[type]);
6700 marker->SetMarkerColor(fMarkerColor[type]);
6701 fMarkers->Add(marker);
6702 marker->Draw();
6703 }
6704 else if (hist==1) // 2-D display via histogram
6705 {
6706 Float_t xfac=90;
6707 Float_t yfac=90;
6708 if (frame=="equ") xfac=6;
6709 if (proj=="angh") yfac=1;
6710 // Reset the histogram if needed
6711 if (clr==1 || proj!=fProj || !fHist[type])
6712 {
6713 if (clr==1 || proj!=fProj)
6714 {
6715 fCanvas->Clear();
6716 fCanvas->SetGrid();
6717 for (Int_t i=0; i<2; i++)
6718 {
6719 if (fHist[i])
6720 {
6721 fHist[i]->Delete();
6722 fHist[i]=0;
6723 }
6724 }
6725 }
6726 if (!fHist[type]) fHist[type]=new TH2F();
6727 fHist[type]->Reset();
6728 fHist[type]->SetMarkerStyle(fMarkerStyle[type]);
6729 fHist[type]->SetMarkerSize(fMarkerSize[type]);
6730 fHist[type]->SetMarkerColor(fMarkerColor[type]);
6731 TString title=titleup;
6732 title+=" ";
6733 title+=titlelow;
6734 fHist[type]->SetNameTitle("SkyMap",title.Data());
6735 fHist[type]->GetXaxis()->SetTitle("Degrees from central Meridian");
6736 if (proj=="angh")
6737 {
6738 fHist[type]->SetBins(1000,-181,181,100,-1.1,1.1);
6739 fHist[type]->GetYaxis()->SetTitle("sin(b)");
6740 }
6741 else
6742 {
6743 fHist[type]->SetBins(1000,-181,181,500,-91,91);
6744 fHist[type]->GetYaxis()->SetTitle("Projected Latitude in degrees");
6745 }
6746 if (frame=="equ")
6747 {
6748 fHist[type]->GetXaxis()->SetTitle("Hours from central Meridian");
6749 if (proj=="angh")
6750 {
6751 fHist[type]->SetBins(200,-12.1,12.1,100,-1.1,1.1);
6752 if (frame=="equ") fHist[type]->GetYaxis()->SetTitle("sin(#delta)");
6753 }
6754 else
6755 {
6756 fHist[type]->SetBins(200,-12.1,12.1,500,-91,91);
6757 if (frame=="equ") fHist[type]->GetYaxis()->SetTitle("Projected Declination in degrees");
6758 }
6759 }
6760 if (frame=="hor")
6761 {
6762 if (proj=="angh")
6763 {
6764 fHist[type]->GetYaxis()->SetTitle("sin(alt)=cos(zenith)");
6765 }
6766 else
6767 {
6768 fHist[type]->GetYaxis()->SetTitle("Projected Altitude in degrees");
6769 }
6770 }
6771 if (frame=="loc")
6772 {
6773 if (proj=="angh")
6774 {
6775 fHist[type]->GetYaxis()->SetTitle("cos(#theta)=sin(b)");
6776 }
6777 else
6778 {
6779 fHist[type]->GetYaxis()->SetTitle("Projected degrees from the equator");
6780 }
6781 }
6782 fProj=proj;
6783 }
6784
6785 if (proj=="merh")
6786 {
6787 fHist[type]->Fill(x*xfac,theta*180./pi);
6788 }
6789 else if (proj=="hamh" || proj=="aith" || proj=="cylh" || proj=="angh")
6790 {
6791 fHist[type]->Fill(x*xfac,y*yfac);
6792 }
6793 else if (proj=="UTh" || proj=="LTh" || proj=="GSTh" || proj=="LSTh") // The 24 hour day view
6794 {
6795 // Set histogram binning and axes attributes
6796 fHist[type]->SetBins(100,0,24,181,-90.5,90.5);
6797 if (!ts) ts=(NcTimestamp*)this;
6798 NcTimestamp tx=(*ts);
6799 Double_t toffset=GetLabTimeOffset();
6800 TString title="Day view";
6801 if (name!="")
6802 {
6803 title+=" of ";
6804 title+=name;
6805 }
6806 title+=" at ";
6807 title+=GetName();
6808 title+=" on ";
6809 TString date;
6810 ts->GetDayTimeString("UT",0,0,&date);
6811 title+=date;
6812 TString tmode="UT";
6813 if (proj=="LTh") tmode="LMT";
6814 if (proj=="GSTh")
6815 {
6816 tmode="GMST";
6817 if (mode=="T") tmode="GAST";
6818 }
6819 if (proj=="LSTh")
6820 {
6821 tmode="LMST";
6822 if (mode=="T") tmode="LAST";
6823 }
6824 if (proj=="UTh") title+=";Universal Time";
6825 if (proj=="LTh") title+=";Local Time";
6826 if (proj=="GSTh") title+=";Greenwich Sidereal Time";
6827 if (proj=="LSTh") title+=";Local Sidereal Time";
6828 if (proj!="UTh")
6829 {
6830 title+=" (";
6831 title+=tmode;
6832 title+=")";
6833 }
6834 title+=" in hours;";
6835 TString ytitle="Declination ";
6836 if (frame=="equ" && mode=="J") ytitle+="(J2000)";
6837 if (frame=="equ" && mode=="B") ytitle+="(B1950)";
6838 if (frame=="equ" && mode=="M") ytitle+="(Mean)";
6839 if (frame=="equ" && mode=="T") ytitle+="(True)";
6840 if (frame=="gal") ytitle="Galactic latitude";
6841 if (frame=="ecl") ytitle="Geocentric Ecliptic latitude";
6842 if (frame=="hor") ytitle="Horizon altitude";
6843 if (frame=="icr") ytitle="ICRS latitude";
6844 if (frame=="loc") ytitle="Angle w.r.t. local frame equator";
6845 ytitle+=" in degrees";
6846 title+=ytitle;
6847 fHist[type]->SetTitle(title);
6848 fHist[type]->SetStats(kFALSE);
6849
6850 // Fill the day view histogram
6851 Double_t hour=0;
6852 Double_t d,a,b;
6853 for (Int_t i=0; i<24; i++)
6854 {
6855 if (tmode=="UT") hour=tx.GetUT();
6856 if (tmode=="LMT") hour=tx.GetLT(toffset);
6857 if (tmode=="GMST") hour=tx.GetGMST();
6858 if (tmode=="GAST") hour=tx.GetGAST();
6859 if (tmode=="LMST") hour=tx.GetLMST(toffset);
6860 if (tmode=="LAST") hour=tx.GetLAST(toffset);
6861
6862 // Get coordinates at this time step
6863 GetSignal(d,a,"deg",b,"deg",frame,&tx,jref,mode,type);
6864
6865 if (frame=="hor") b=90.-b;
6866 if (frame=="loc") b=90.-a;
6867
6868 fHist[type]->Fill(hour,b);
6869
6870 tx.Add(1); // Add 1 hour for each time step
6871 }
6872
6873 // Restore the original timestamp for Solar system objects
6874 SetSolarSystem(namesave,&tsave,type);
6875 }
6876 else if (proj=="UYh" || proj=="LYh" || proj=="GSYh" || proj=="LSYh") // The day of the year view
6877 {
6878 // Set histogram binning and axes attributes
6879 fHist[type]->SetBins(1500,0,370,181,-90.5,90.5);
6880 if (!ts) ts=(NcTimestamp*)this;
6881 NcTimestamp tx=(*ts);
6882 Double_t toffset=GetLabTimeOffset();
6883 TString year="";
6884 year+=int(ts->GetEpoch("J"));
6885 TString tmode="UT";
6886 if (proj=="LYh") tmode="LMT";
6887 if (proj=="GSYh")
6888 {
6889 tmode="GMST";
6890 if (mode=="T") tmode="GAST";
6891 }
6892 if (proj=="LSYh")
6893 {
6894 tmode="LMST";
6895 if (mode=="T") tmode="LAST";
6896 }
6897 TString time;
6898 if (proj=="UYh" || proj=="GSYh") ts->GetDayTimeString(tmode,0,0,0,&time);
6899 if (proj=="LYh" || proj=="LSYh") ts->GetDayTimeString(tmode,0,toffset,0,&time);
6900
6901 TString title="Year view";
6902 if (name!="")
6903 {
6904 title+=" of ";
6905 title+=name;
6906 }
6907 title+=" at ";
6908 title+=GetName();
6909 title+=" in ";
6910 title+=year;
6911 title+=" at ";
6912 title+=time;
6913 title+=";Day of the year;";
6914 TString ytitle="Declination ";
6915 if (frame=="equ" && mode=="J") ytitle+="(J2000)";
6916 if (frame=="equ" && mode=="B") ytitle+="(B1950)";
6917 if (frame=="equ" && mode=="M") ytitle+="(Mean)";
6918 if (frame=="equ" && mode=="T") ytitle+="(True)";
6919 if (frame=="gal") ytitle="Galactic latitude";
6920 if (frame=="ecl") ytitle="Geocentric Ecliptic latitude";
6921 if (frame=="hor") ytitle="Horizon altitude";
6922 if (frame=="icr") ytitle="ICRS latitude";
6923 if (frame=="loc") ytitle="Angle w.r.t. local frame equator";
6924 ytitle+=" in degrees";
6925 title+=ytitle;
6926 fHist[type]->SetTitle(title);
6927 fHist[type]->SetStats(kFALSE);
6928
6929 // Fill the year view histogram
6930 // Start at 01-jan 00:00:00h for the corresponding year at the selected location
6931 // and then set the time according to the specified timestamp
6932 Double_t hour=0;
6933 if (proj=="UYh" || proj=="GSYh") // Location is Greenwich
6934 {
6935 tx.SetUT(year.Atoi(),1,1,"00:00:00");
6936 hour=ts->GetUT();
6937 }
6938 if (proj=="LYh" || proj=="LSYh") // The lab location
6939 {
6940 tx.SetLT(toffset,year.Atoi(),1,1,"00:00:00");
6941 hour=ts->GetLT(toffset);
6942 }
6943 tx.Add(hour); // Set the selected time
6944
6945 Double_t d,a,b;
6946 Int_t day=0;
6947 for (Int_t i=0; i<367; i++)
6948 {
6949
6950 // Get coordinates at this time step
6951 GetSignal(d,a,"deg",b,"deg",frame,&tx,jref,mode,type);
6952
6953 if (frame=="hor") b=90.-b;
6954 if (frame=="loc") b=90.-a;
6955
6956 if (proj=="UYh" || proj=="GSYh") day=tx.GetDayOfYear();
6957 if (proj=="LYh" || proj=="LSYh") day=tx.GetDayOfYear(kFALSE,toffset);
6958
6959 fHist[type]->Fill(day,b);
6960
6961 tx.Add(24); // Add 1 day (= 24 hours) for each time step
6962 }
6963
6964 // Restore the original timestamp for Solar system objects
6965 SetSolarSystem(namesave,&tsave,type);
6966 }
6967
6968 // Draw the selected histogram
6969 if ((!type && fHist[1]) || (type && fHist[0]))
6970 {
6971 fHist[type]->Draw("same");
6972 }
6973 else
6974 {
6975 fHist[type]->Draw();
6976
6977 // Draw a horizontal thick line to mark the horizon c.q. equator for the day and year views
6978 if (proj=="UTh" || proj=="LTh" || proj=="GSTh" || proj=="LSTh" ||
6979 proj=="UYh" || proj=="LYh" || proj=="GSYh" || proj=="LSYh")
6980 {
6981 if (!fMarkers)
6982 {
6983 fMarkers=new TObjArray();
6984 fMarkers->SetOwner();
6985 }
6986 TLine* line=0;
6987 if (proj=="UTh" || proj=="LTh" || proj=="GSTh" || proj=="LSTh") line=new TLine(0,0,24,0);
6988 if (proj=="UYh" || proj=="LYh" || proj=="GSYh" || proj=="LSYh") line=new TLine(0,0,370,0);
6989 if (line)
6990 {
6991 line->SetLineWidth(3);
6992 fMarkers->Add(line);
6993 line->Draw();
6994 }
6995 }
6996 }
6997 }
6998}
6999
7000void NcAstrolab::DisplaySignal(TString frame,TString mode,NcTimestamp* ts,TString name,TString proj,Int_t clr,Int_t type)
7001{
7091
7092 // Create a signal for a solar system object if needed
7093 Double_t d,a,b;
7094 GetSignal(d,a,"deg",b,"deg",frame,ts,name,mode,type);
7095
7096 Int_t j=GetSignalIndex(name,type);
7097 if (j>0)
7098 {
7099 if (type) j=-j;
7100 DisplaySignal(frame,mode,ts,j,proj,clr,name);
7101 }
7102
7103 // Update the canvas so that the Skymap GUI immediately shows the result
7104 if (fCanvas) fCanvas->Update();
7105}
7106
7107void NcAstrolab::DisplaySignals(TString frame,TString mode,NcTimestamp* ts,TString proj,Int_t clr,Int_t nmax,Int_t j,Int_t type,TString name)
7108{
7203
7204 NcSignal* sx=0;
7205 TString namex="";
7206 NcTimestamp* tx=0;
7207 Int_t jdisp=0;
7208
7209 // Display stored reference signals
7210 if (fRefs && type<=0)
7211 {
7212 // Use timestamp of j-th measurement if requested
7213 if (j>0)
7214 {
7215 sx=GetSignal(j,1);
7216 if (sx) tx=sx->GetTimestamp();
7217 }
7218
7219 // Use the provided timestamp
7220 if (!j || !tx) tx=ts;
7221
7222 // Use the current lab timestamp if no timestamp selected
7223 if (!tx) tx=(NcTimestamp*)this;
7224
7225 jdisp=0;
7226 for (Int_t i=1; i<=fRefs->GetSize(); i++)
7227 {
7228 sx=GetSignal(i,0);
7229 if (!sx) continue;
7230
7231 jdisp++;
7232 if (nmax>=0 && jdisp>nmax) break;
7233
7234 // Check for the name pattern
7235 namex=sx->GetName();
7236 if (name!="*" && !namex.Contains(name)) continue;
7237
7238 // Use the actual timestamp of the reference signal
7239 if (j<0)
7240 {
7241 tx=sx->GetTimestamp();
7242 if (!tx) tx=ts;
7243 if (!tx) tx=(NcTimestamp*)this;
7244 }
7245
7246 if (name=="*")
7247 {
7248 DisplaySignal(frame,mode,tx,i,proj,clr);
7249 }
7250 else
7251 {
7252 DisplaySignal(frame,mode,tx,i,proj,clr,name);
7253 }
7254 clr=0; // No display clear for subsequent signals
7255 }
7256 }
7257
7258 // Display all stored measurements
7259 if (fSigs && type)
7260 {
7261 jdisp=0;
7262 for (Int_t j=1; j<=fSigs->GetSize(); j++)
7263 {
7264 sx=GetSignal(j,1);
7265 if (!sx) continue;
7266
7267 jdisp++;
7268 if (nmax>=0 && jdisp>nmax) break;
7269
7270 // Check for the name pattern
7271 namex=sx->GetName();
7272 if (name!="*" && !namex.Contains(name)) continue;
7273
7274 tx=sx->GetTimestamp();
7275 if (!tx) tx=ts;
7276 if (!tx) tx=(NcTimestamp*)this;
7277 if (name=="*")
7278 {
7279 DisplaySignal(frame,mode,tx,-j,proj,clr);
7280 }
7281 else
7282 {
7283 DisplaySignal(frame,mode,tx,-j,proj,clr,name);
7284 }
7285 clr=0; // No display clear for subsequent signals
7286 }
7287 }
7288
7289 // Update the canvas so that the Skymap GUI immediately shows the result
7290 if (fCanvas) fCanvas->Update();
7291}
7292
7293void NcAstrolab::SetMarkerSize(Float_t size,Int_t type)
7294{
7306
7307 if (type<0 || type >3) return;
7308
7309 fMarkerSize[type]=size;
7310}
7311
7312void NcAstrolab::SetMarkerStyle(Int_t style,Int_t type)
7313{
7325
7326 if (type<0 || type >3) return;
7327
7328 fMarkerStyle[type]=style;
7329}
7330
7331void NcAstrolab::SetMarkerColor(Int_t color,Int_t type)
7332{
7344
7345 if (type<0 || type >3) return;
7346
7347 fMarkerColor[type]=color;
7348}
7349
7350void NcAstrolab::SetCentralMeridian(Int_t mode,Double_t phi,TString u)
7351{
7375
7376 fMeridian=ConvertAngle(phi,u,"rad");
7377 fUsMeridian=0;
7378 if (mode>0) fUsMeridian=1;
7379 if (mode<0) fUsMeridian=-1;
7380 Double_t pi=acos(-1.);
7381 Double_t twopi=2.*pi;
7382 // Set range to 0 <= meridian < 2pi
7383 while (fMeridian>=twopi)
7384 {
7385 fMeridian-=twopi;
7386 }
7387 while (fMeridian<0)
7388 {
7389 fMeridian+=twopi;
7390 }
7391 // Prevent accuracy problems
7392 if (fMeridian>0) fMeridian+=1.e-6;
7393}
7394
7395void NcAstrolab::Project(Double_t l,Double_t b,TString proj,Double_t& x,Double_t& y)
7396{
7427
7428 Double_t pi=acos(-1.);
7429
7430 // Subtract central meridian from longitude
7431 l-=fMeridian;
7432
7433 // Take l between -180 and 180 degrees
7434 while (l>pi)
7435 {
7436 l-=2.*pi;
7437 }
7438 while (l<-pi)
7439 {
7440 l+=2.*pi;
7441 }
7442
7443 x=0;
7444 y=0;
7445
7446 // Convert (l,b) to (x,y) with -2 < x <= 2
7447 if (proj=="cyl" || proj=="cylh") ProjectCylindrical(l,b,x,y);
7448 if (proj=="ham" || proj=="hamh") ProjectHammer(l,b,x,y);
7449 if (proj=="ait" || proj=="aith") ProjectAitoff(l,b,x,y);
7450 if (proj=="mer" || proj=="merh") ProjectMercator(l,b,x,y);
7451 if (proj=="ang" || proj=="angh")
7452 {
7453 x=2.*l/pi;
7454 y=sin(b);
7455 }
7456}
7457
7458void NcAstrolab::ProjectCylindrical(Double_t l,Double_t b,Double_t& x, Double_t& y)
7459{
7468
7469 Double_t pi=acos(-1.);
7470 x=2.*l/pi;
7471 y=2.*b/pi;
7472}
7473
7474void NcAstrolab::ProjectHammer(Double_t l,Double_t b,Double_t& x,Double_t& y)
7475{
7485
7486 Double_t k=1./sqrt(1.+cos(b)*cos(l/2.));
7487 x=2.*k*cos(b)*sin(l/2.);
7488 y=k*sin(b);
7489}
7490
7491void NcAstrolab::ProjectAitoff(Double_t l,Double_t b,Double_t& x,Double_t& y)
7492{
7501
7502 Double_t pi=acos(-1.);
7503 x=0;
7504 y=0;
7505 Double_t k=acos(cos(b)*cos(l/2.));
7506 if(sin(k)!=0)
7507 {
7508 x=4.*k*cos(b)*sin(l/2.)/(pi*sin(k));
7509 y=2.*k*sin(b)/(pi*sin(k));
7510 }
7511}
7512
7513void NcAstrolab::ProjectMercator(Double_t l,Double_t b,Double_t& x,Double_t& y)
7514{
7529
7530 Double_t pi=acos(-1.);
7531 Double_t bcut=85.051*pi/180.; // Latitude cut off value in radians
7532
7533 x=2.*l/pi;
7534 y=0;
7535 if (b > bcut) b=bcut;
7536 if (b < -bcut) b=-bcut;
7537 y=0.5*log((1.+sin(b))/(1.-sin(b)))/pi;
7538}
7539
7540void NcAstrolab::SetPhysicalParameter(TString name,Double_t value)
7541{
7579
7580 // Variable to correct conversion factors when a parameter is modified
7581 Double_t frac=1;
7582
7583 if (name=="SpeedC")
7584 {
7585 frac=value/fSpeedC;
7586 fSpeedC=value;
7587 fMe*=frac*frac;
7588 fMmu*=frac*frac;
7589 fMtau*=frac*frac;
7590 fAmu*=frac*frac;
7591 fMp*=frac*frac;
7592 fMn*=frac*frac;
7593 fMW*=frac*frac;
7594 fMZ*=frac*frac;
7595 fHbarc*=frac;
7596 fHbarc2*=pow(frac,2.);
7597 }
7598 if (name=="Qe")
7599 {
7600 frac=value/fQe;
7601 fQe=value;
7602 fMe/=frac;
7603 fMmu/=frac;
7604 fMtau/=frac;
7605 fAmu/=frac;
7606 fMp/=frac;
7607 fMn/=frac;
7608 fMW/=frac;
7609 fMZ/=frac;
7610 fHbar/=frac;
7611 fHbarc/=frac;
7612 fHbarc2/=pow(frac,2.);
7613 }
7614 if (name=="Me") fMe=value;
7615 if (name=="Mmu") fMmu=value;
7616 if (name=="Mtau") fMtau=value;
7617 if (name=="Amu")
7618 {
7619 frac=value/fAmu;
7620 fAmu=value;
7621 fMp*=frac;
7622 fMn*=frac;
7623 }
7624 if (name=="Mp") fMp=value;
7625 if (name=="Mn") fMn=value;
7626 if (name=="MW") fMW=value;
7627 if (name=="GammaW") fGammaW=value;
7628 if (name=="MZ") fMZ=value;
7629 if (name=="GammaZ") fGammaZ=value;
7630 if (name=="AlphaEM") fAlphaEM=value;
7631 if (name=="Fermi") fFermi=value;
7632 if (name=="Planck")
7633 {
7634 frac=value/fPlanck;
7635 fPlanck=value;
7636 fHbar*=frac;
7637 fHbarc*=frac;
7638 fFermi/=pow(frac,3.);
7639 }
7640 if (name=="Boltz") fBoltz=value;
7641 if (name=="Newton")
7642 {
7643 frac=value/fNewton;
7644 fNewton=value;
7645 fGn*=frac;
7646 }
7647 if (name=="Gn") fGn=value;
7648 if (name=="Au") fAu=value;
7649 if (name=="Pc") fPc=value;
7650 if (name=="Hubble") fHubble=value;
7651 if (name=="OmegaM") fOmegaM=value;
7652 if (name=="OmegaR") fOmegaR=value;
7653 if (name=="OmegaL") fOmegaL=value;
7654 if (name=="OmegaB") fOmegaB=value;
7655 if (name=="OmegaC") fOmegaC=value;
7656}
7657
7658Double_t NcAstrolab::GetPhysicalParameter(TString name) const
7659{
7681
7682 Double_t val=0;
7683
7684 // Standard parameters
7685 if (name=="SpeedC") return fSpeedC;
7686 if (name=="Qe") return fQe;
7687 if (name=="Me") return fMe;
7688 if (name=="Mmu") return fMmu;
7689 if (name=="Mtau") return fMtau;
7690 if (name=="Amu") return fAmu;
7691 if (name=="Mp") return fMp;
7692 if (name=="Mn") return fMn;
7693 if (name=="MW") return fMW;
7694 if (name=="GammaW") return fGammaW;
7695 if (name=="GammaZ") return fGammaZ;
7696 if (name=="AlphaEM") return fAlphaEM;
7697 if (name=="Fermi") return fFermi;
7698 if (name=="Planck") return fPlanck;
7699 if (name=="Boltz") return fBoltz;
7700 if (name=="Newton") return fNewton;
7701 if (name=="Gn") return fGn;
7702 if (name=="Au") return fAu;
7703 if (name=="Pc") return fPc;
7704 if (name=="Hubble") return fHubble;
7705 if (name=="OmegaM") return fOmegaM;
7706 if (name=="OmegaR") return fOmegaR;
7707 if (name=="OmegaL") return fOmegaL;
7708 if (name=="OmegaB") return fOmegaB;
7709 if (name=="OmegaC") return fOmegaC;
7710
7711 // Derived parameters
7712 if (name=="Hbar") return fHbar;
7713 if (name=="Hbarc") return fHbarc;
7714 if (name=="Hbarc2") return fHbarc2;
7715 if (name=="Mnucl")
7716 {
7717 val=(fMp+fMn)/2.;
7718 return val;
7719 }
7720 if (name=="Sin2w")
7721 {
7722 val=1.-pow(fMW/fMZ,2.);
7723 return val;
7724 }
7725 if (name=="Jy") return 1e-23;
7726 if (name=="Erg")
7727 {
7728 val=1e-7/(fQe*1e9);
7729 return val;
7730 }
7731
7732 // Unknown parameter
7733 return 0;
7734}
7735
7736Double_t NcAstrolab::GetPhysicalDistance(Double_t z,TString u,Int_t t) const
7737{
7771
7772 if (z<=0 || fHubble<=0) return 0;
7773
7774 Double_t c=fSpeedC/1000.; // Lightspeed in km/s
7775
7776 TF1 f("f","1./sqrt([0]*pow((1.+x),4)+[1]*pow((1.+x),3)+[2])");
7777
7778 f.SetParameter(0,fOmegaR);
7779 f.SetParameter(1,fOmegaM);
7780 f.SetParameter(2,fOmegaL);
7781 f.SetRange(0,z);
7782
7783 Double_t dist=f.Integral(0,z);
7784 dist*=c/fHubble; // The distance in Mpc
7785
7786 Double_t distm=dist*1e6*fPc; // corresponding distance in meter
7787
7788 Double_t val=0;
7789
7790 if (u=="Gpc") val=dist*1e-3;
7791 if (u=="Mpc") val=dist;
7792 if (u=="pc") val=dist*1e6;
7793 if (u=="ly") val=dist*3.26156e6;
7794 if (u=="m") val=distm;
7795 if (u=="km") val=distm*1e-3;
7796 if (u=="cm") val=distm*1e2;
7797
7798 if (!t) val=val/(z+1.);
7799
7800 return val;
7801}
7802
7803Double_t NcAstrolab::GetProperDistance(Double_t z,TString u,Int_t t) const
7804{
7838
7839 Double_t val=GetPhysicalDistance(z,u,t);
7840
7841 return val;
7842}
7843
7844Double_t NcAstrolab::GetComovingDistance(Double_t z,TString u) const
7845{
7876
7877 Double_t val=GetPhysicalDistance(z,u,1);
7878
7879 return val;
7880}
7881
7882Double_t NcAstrolab::GetLuminosityDistance(Double_t z,TString u) const
7883{
7917
7918 Double_t val=GetPhysicalDistance(z,u,1);
7919 val=val*(z+1.);
7920
7921 return val;
7922}
7923
7924Double_t NcAstrolab::GetLightTravelDistance(Double_t z,TString u) const
7925{
7959
7960 if (z<=0 || fHubble<=0) return 0;
7961
7962 Double_t c=fSpeedC/1000.; // Lightspeed in km/s
7963
7964 TF1 f("f","1./((1.+x)*sqrt([0]*pow((1.+x),4)+[1]*pow((1.+x),3)+[2]))");
7965
7966 f.SetParameter(0,fOmegaR);
7967 f.SetParameter(1,fOmegaM);
7968 f.SetParameter(2,fOmegaL);
7969 f.SetRange(0,z);
7970
7971 Double_t dist=f.Integral(0,z);
7972 dist*=c/fHubble; // The distance in Mpc
7973
7974 Double_t distm=dist*1e6*fPc; // corresponding distance in meter
7975
7976 Double_t val=0;
7977
7978 if (u=="Gpc") val=dist*1e-3;
7979 if (u=="Mpc") val=dist;
7980 if (u=="pc") val=dist*1e6;
7981 if (u=="ly") val=dist*3.26156e6;
7982 if (u=="m") val=distm;
7983 if (u=="km") val=distm*1e-3;
7984 if (u=="cm") val=distm*1e2;
7985
7986 return val;
7987}
7988
7989Double_t NcAstrolab::GetLightTravelTime(Double_t z) const
7990{
8008
8009 Double_t val=GetLightTravelDistance(z,"ly");
8010
8011 return val;
8012}
8013
8014Double_t NcAstrolab::GetHubbleParameter(Double_t z,TString u) const
8015{
8036
8037 if (z<0 || fHubble<=0) return 0;
8038
8039 TF1 f("f","sqrt([0]*pow((1.+x),4)+[1]*pow((1.+x),3)+[2])");
8040
8041 f.SetParameter(0,fOmegaR);
8042 f.SetParameter(1,fOmegaM);
8043 f.SetParameter(2,fOmegaL);
8044 f.SetRange(0,z);
8045
8046 Double_t H=f.Eval(z);
8047 H*=fHubble; // The current Hubble parameter (H0) in km/s per Mpc
8048
8049 Double_t Hm=H/(1e6*fPc); // corresponding H in km/s per meter
8050
8051 Double_t val=0;
8052
8053 if (u=="Gpc") val=H/1e-3;
8054 if (u=="Mpc") val=H;
8055 if (u=="pc") val=H/1e6;
8056 if (u=="ly") val=H/3.26156e6;
8057 if (u=="m") val=Hm;
8058 if (u=="km") val=Hm/1e-3;
8059 if (u=="cm") val=Hm/1e2;
8060
8061 return val;
8062}
8063
8064Double_t NcAstrolab::GetNuclearMass(Int_t Z,Int_t N,Int_t mode) const
8065{
8093
8094 if (Z<0 || N<0) return 0;
8095
8096 Double_t rz=Z;
8097 Double_t rn=N;
8098 Double_t ra=Z+N;
8099
8100 // Coefficients from a recent fit mentioned in Tipler's modern physics (4th ed.) textbook.
8101 // The values in the comment field are the ones of the slides mentioned above.
8102 Double_t a=15.67; //15.835;
8103 Double_t b=17.23; //18.33;
8104 Double_t s=23.2; //23.20;
8105 Double_t d=0.75; //0.714;
8106 Double_t delta=12; //11.2;
8107
8108 Double_t term1=a*ra; // Constant bulk binding energy like cohesion in a liquid
8109 Double_t term2=b*pow(ra,2./3.); // Surface energy of a sphere like surface tension of liquids
8110 Double_t term3=s*pow((rn-rz),2.)/ra; // Symmetry term
8111 Double_t term4=d*pow(rz,2.)/pow(ra,1./3.); // Coulomb term
8112 Double_t term5=0; // Phenomenological correction for light nuclei (pairing energy term)
8113
8114 Int_t oz=Z%2; // Flag (1) for odd Z nuclei
8115 Int_t on=N%2; // Flag (1) for odd N nuclei
8116
8117 if (oz && on) term5=delta/sqrt(ra);
8118 if (!oz && !on) term5=-delta/sqrt(ra);
8119
8120 // Binding energy in MeV
8121 Double_t bnz=term1-term2-term3-term4-term5;
8122
8123 // In case a single nucleon was specified
8124 if ((Z+N)<2)
8125 {
8126 bnz=0;
8127 ra=1;
8128 }
8129
8130 // Nuclear mass in MeV/c^2
8131 Double_t mass=rz*fMp+rn*fMn-bnz;
8132
8133 // Explicit literature values for very light elements
8134 if (Z==1 && N==1) // Deuteron
8135 {
8136 mass=2.013553212712*fAmu;
8137 bnz=rz*fMp+rn*fMn-mass;
8138 }
8139
8140 if (Z==1 && N==2) // Triton
8141 {
8142 mass=3.0155007134*fAmu;
8143 bnz=rz*fMp+rn*fMn-mass;
8144 }
8145
8146 if (Z==2 && N==1) // Helion
8147 {
8148 mass=3.0149322468*fAmu;
8149 bnz=rz*fMp+rn*fMn-mass;
8150 }
8151
8152 if (Z==2 && N==2) // Alpha
8153 {
8154 mass=4.001506179125*fAmu;
8155 bnz=rz*fMp+rn*fMn-mass;
8156 }
8157
8158 Double_t value=0;
8159
8160 switch(mode)
8161 {
8162 case 1 : // Nuclear mass in GeV/c^2
8163 value=mass/1000.;
8164 break;
8165
8166 case -1 : // Nuclear mass in amu
8167 value=mass/fAmu;
8168 break;
8169
8170 case 2 : // Total binding energy in MeV
8171 value=bnz;
8172 break;
8173
8174 case -2 : // Total binding energy in amu
8175 value=bnz/fAmu;
8176 break;
8177
8178 case 3 : // Binding energy per nucleon in MeV
8179 value=bnz/ra;
8180 break;
8181
8182 case -3 : // Binding energy per nucleon in amu
8183 value=bnz/(fAmu*ra);
8184 break;
8185 }
8186
8187 return value;
8188}
8189
8190Double_t NcAstrolab::GetRadiationLength(Double_t Z,Double_t A,Double_t rho) const
8191{
8220
8221 Double_t X0=-1;
8222
8223 if (Z<=0 || A<1 || A<Z) return -1;
8224
8225 X0=716.4*A/(Z*(Z+1.)*(log(287./sqrt(Z))));
8226
8227 Double_t mN=0.001*fGn*fQe/fAmu; // The nucleon mass in gram
8228 if (rho==0) X0=X0/mN;
8229 if (rho>0) X0=X0/rho;
8230
8231 return X0;
8232}
8233
8234Double_t NcAstrolab::GetMeanFreePath(Double_t sigma,Double_t rho,Int_t mode) const
8235{
8270
8271 Double_t lambda=-1;
8272
8273 if (sigma<=0 || rho<=0 || mode<0 || mode>4) return -1;
8274
8275 Double_t mN=0.001*fGn*fQe/fAmu; // The nucleon mass in gram
8276 Double_t n=fabs(rho)/mN; // The number of nucleons per cm^3
8277 if (mode<2) n=rho; // The number of scattering centers per cm^3
8278 sigma=sigma*1e-24; // Convert to cm^2
8279
8280 lambda=1./(sigma*n);
8281
8282 if (mode==1 || mode==4) lambda=lambda*n;
8283 if (mode==3) lambda=lambda*rho;
8284
8285 return lambda;
8286}
8287
8288Double_t NcAstrolab::GetInteractionProbability(Double_t x,Double_t lambda) const
8289{
8320
8321 Double_t prob=-1;
8322
8323 if (x<0 || lambda<=0) return -1;
8324
8325 prob=1.-exp(-x/lambda);
8326
8327 return prob;
8328}
8329
8330Double_t NcAstrolab::GetInteractionProbability(Double_t x,Double_t sigma,Double_t rho,Int_t mode) const
8331{
8363
8364 Double_t prob=-1;
8365
8366 Double_t lambda=GetMeanFreePath(sigma,rho,mode);
8367
8368 if (lambda>0) prob=GetInteractionProbability(x,lambda);
8369
8370 return prob;
8371}
8372
8373Double_t NcAstrolab::GetSurvivalProbability(Double_t x,Double_t lambda) const
8374{
8405
8406 Double_t prob=-1;
8407
8408 if (x<0 || lambda<=0) return -1;
8409
8410 prob=exp(-x/lambda);
8411
8412 return prob;
8413}
8414
8415Double_t NcAstrolab::GetSurvivalProbability(Double_t x,Double_t sigma,Double_t rho,Int_t mode) const
8416{
8448
8449 Double_t prob=-1;
8450
8451 Double_t lambda=GetMeanFreePath(sigma,rho,mode);
8452
8453 if (lambda>0) prob=GetSurvivalProbability(x,lambda);
8454
8455 return prob;
8456}
8457
8458Double_t NcAstrolab::GetShieldingThickness(Double_t prob,Double_t lambda) const
8459{
8487
8488 Double_t x=-1;
8489
8490 if (prob<=0 || prob>1 || lambda<=0) return -1;
8491
8492 x=-lambda*log(prob);
8493
8494 return x;
8495}
8496
8497Double_t NcAstrolab::GetShieldingThickness(Double_t prob,Double_t sigma,Double_t rho,Int_t mode) const
8498{
8527
8528 Double_t x=-1;
8529
8530 if (prob<=0 || prob>1) return -1;
8531
8532 Double_t lambda=GetMeanFreePath(sigma,rho,mode);
8533
8534 if (lambda>0) x=GetShieldingThickness(prob,lambda);
8535
8536 return x;
8537}
8538
8539Double_t NcAstrolab::GetTargetThickness(Double_t prob,Double_t lambda) const
8540{
8568
8569 if (prob<=0 || prob>1 || lambda<=0) return -1;
8570
8571 Double_t p=1.-prob;
8572 Double_t x=GetShieldingThickness(p,lambda);
8573
8574 return x;
8575}
8576
8577Double_t NcAstrolab::GetTargetThickness(Double_t prob,Double_t sigma,Double_t rho,Int_t mode) const
8578{
8607
8608 Double_t x=-1;
8609
8610 if (prob<=0 || prob>1) return -1;
8611
8612 Double_t lambda=GetMeanFreePath(sigma,rho,mode);
8613
8614 Double_t p=1.-prob;
8615 if (lambda>0) x=GetShieldingThickness(p,lambda);
8616
8617 return x;
8618}
8619
8620Double_t NcAstrolab::GetNeutrinoXsection(Int_t mode,Int_t type,Double_t egev,Double_t xscale,Double_t* eprimgev,Double_t* alpha) const
8621{
8668
8669 if (eprimgev) *eprimgev=0;
8670 if (alpha) *alpha=0;
8671 if (!mode || mode>3 || mode<-4 || !type || abs(type)>3) return 0;
8672
8673 const Double_t fnumuccn=6.77e-15; // Nu_mu+Nucleon CC sigma/E in barn/GeV
8674 const Double_t fanumuccn=3.34e-15; // Anti-Nu_mu+Nucleon CC sigma/E in barn/GeV
8675
8676 const Double_t sinw2=GetPhysicalParameter("Sin2w"); // sin^2 of the Weinberg angle
8677
8678 const Double_t fnuetote=0.25+sinw2+4.*pow(sinw2,2.)/3.; // Nu_e+e total sigma/sigma0
8679 const Double_t fanuetote=(1./12.)+(sinw2/3.)+4.*pow(sinw2,2.)/3.; // Anti-Nu_e+e total sigma/sigma0
8680 Double_t fnumucce=1.; // Nu_mu+e CC sigma/sigma0
8681 const Double_t fnumunce=0.25-sinw2+4.*pow(sinw2,2.)/3.; // Nu_mu+e NC sigma/sigma0
8682 const Double_t fanumunce=(1./12.)-(sinw2/3.)+4.*pow(sinw2,2.)/3.; // Anti-Nu_mu+e NC sigma/sigma0
8683 const Double_t f4=1./3.; // Anti-Nu_e+e-->Anti-Nu_mu+mu CC sigma/sigma0
8684
8685 // Parameters for the (anti)neutrino+Nucleon cross section parametrisations of Conolly et al.
8686 const Double_t c0nu=-1.826;
8687 const Double_t c1nu=-17.31;
8688 const Double_t c2nunc=-6.448;
8689 const Double_t c2nucc=-6.406;
8690 const Double_t c3nu=1.431;
8691 const Double_t c4nunc=-18.61;
8692 const Double_t c4nucc=-17.91;
8693 const Double_t c0anu=-1.033;
8694 const Double_t c1anu=-15.95;
8695 const Double_t c2anunc=-7.296;
8696 const Double_t c2anucc=-7.247;
8697 const Double_t c3anu=1.569;
8698 const Double_t c4anunc=-18.30;
8699 const Double_t c4anucc=-17.72;
8700
8701 Double_t rncnu=0.2261/0.7221; // sigma_nc/sigma_cc for Neutrino+Nucleon DIS at 100 GeV
8702 Double_t rncanu=0.1307/0.3747; // sigma_nc/sigma_cc for Anti-neutrino+Nucleon DIS at 100 GeV
8703
8704 // Average inelasticity (y) values from Gandhi et al.
8705 Double_t ynucc[12]={0.483,0.477,0.472,0.426,0.332,0.237,0.250,0.237,0.225,0.216,0.208,0.205};
8706 Double_t ynunc[12]={0.474,0.470,0.467,0.428,0.341,0.279,0.254,0.239,0.227,0.217,0.210,0.207};
8707 Double_t yanucc[12]={0.333,0.340,0.354,0.345,0.301,0.266,0.249,0.237,0.225,0.216,0.208,0.205};
8708 Double_t yanunc[12]={0.350,0.354,0.368,0.358,0.313,0.273,0.253,0.239,0.227,0.217,0.210,0.207};
8709
8710 Double_t loge=log10(egev);
8711 Double_t y=0;
8712 Int_t index=int(loge+0.5);
8713 if (index<1) index=1;
8714 if (index>12) index=12;
8715 if (eprimgev)
8716 {
8717 if (type>0) // Neutrinos
8718 {
8719 if (abs(mode)==1) y=ynucc[index-1];
8720 if (abs(mode)==2) y=ynunc[index-1];
8721 if (mode==3) y=(ynucc[index-1]+rncnu*ynunc[index-1])/(1.+rncnu);
8722 if (mode==-3) y=(ynucc[index-1]+fnumunce*ynunc[index-1])/(1.+fnumunce);
8723 }
8724 else // Anti-neutrinos
8725 {
8726 if (abs(mode)==1) y=yanucc[index-1];
8727 if (abs(mode)==2) y=yanunc[index-1];
8728 if (mode==3) y=(yanucc[index-1]+rncanu*yanunc[index-1])/(1.+rncanu);
8729 if (mode==-3) y=(yanucc[index-1]+fnumunce*yanunc[index-1])/(1.+fnumunce);
8730 }
8731 *eprimgev=egev*(1.-y);
8732 }
8733
8734 if (alpha)
8735 {
8736 Double_t mtarg=fMe;
8737 if (mode>0) mtarg=GetPhysicalParameter("Mnucl");
8738 *alpha=sqrt(2.e-3*mtarg/egev)*y*180./((1.-y)*acos(-1.));
8739 }
8740
8741 Double_t xsec=0;
8742 Double_t fact=0;
8743 Double_t c0=0,c1=0,c2=0,c3=0,c4=0;
8744
8745 if (mode>0) // DIS on Nucleon target
8746 {
8747 if (mode==3) // Total xsec
8748 {
8749 // Recursive invokation for NC+CC cross section
8750 xsec=GetNeutrinoXsection(1,type,egev,xscale);
8751 xsec+=GetNeutrinoXsection(2,type,egev,xscale);
8752 return xsec;
8753 }
8754 if (egev<1e4) // Energy below 10 TeV
8755 {
8756 if (mode==1) // CC xsec
8757 {
8758 fact=fnumuccn;
8759 if (type<0) fact=fanumuccn;
8760 }
8761 if (mode==2) // NC xsec
8762 {
8763 fact=fnumuccn*rncnu;
8764 if (type<0) fact=fanumuccn*rncanu;
8765 }
8766 xsec=fact*egev;
8767 }
8768 else // Energy of 10 TeV and above
8769 {
8770 if (mode==1) // CC xsec
8771 {
8772 if (type>0)
8773 {
8774 c0=c0nu;
8775 c1=c1nu;
8776 c2=c2nucc;
8777 c3=c3nu;
8778 c4=c4nucc;
8779 }
8780 else
8781 {
8782 c0=c0anu;
8783 c1=c1anu;
8784 c2=c2anucc;
8785 c3=c3anu;
8786 c4=c4anucc;
8787 }
8788 }
8789 if (mode==2) // NC xsec
8790 {
8791 if (type>0)
8792 {
8793 c0=c0nu;
8794 c1=c1nu;
8795 c2=c2nunc;
8796 c3=c3nu;
8797 c4=c4nunc;
8798 }
8799 else
8800 {
8801 c0=c0anu;
8802 c1=c1anu;
8803 c2=c2anunc;
8804 c3=c3anu;
8805 c4=c4anunc;
8806 }
8807 }
8808 Double_t lne=log(loge-c0);
8809 Double_t logsigma=c1+c2*lne+c3*pow(lne,2.)+c4/lne; // Log10(sigma) in cm^2
8810 logsigma+=24.;
8811 xsec=pow(10.,logsigma);
8812 }
8813 }
8814 else // Scattering on electron target
8815 {
8816 // Check whether we are in the Glashow resonance regime
8817 Double_t elow=pow((fMW-2.*fGammaW),2.)/(2.e-3*fMe);
8818 Double_t eup=pow((fMW+2.*fGammaW),2.)/(2.e-3*fMe);
8819 if (mode==-3 && type==-1 && egev>elow && egev<eup) // Total xsec at Glashow resonance
8820 {
8821 xsec=5.02e-7/xscale;
8822 if (eprimgev) *eprimgev=0;
8823 if (alpha) *alpha=0;
8824 return xsec;
8825 }
8826
8827 // Check if we are above the kinematical threshold energy for CC scattering
8828 Double_t mlepton=fMe;
8829 if (abs(type)==2) mlepton=fMmu;
8830 if (abs(type)==3) mlepton=fMtau;
8831 Double_t eth=1.e-3*(pow(mlepton,2.)-pow(fMe,2.))/(2.*fMe);
8832
8833 if (egev<eth) // Below CC kinematical threshold
8834 {
8835 fnumucce=0;
8836 if (mode==-1) // CC xsec was requested
8837 {
8838 if (eprimgev) *eprimgev=egev;
8839 if (alpha) *alpha=0;
8840 return 0;
8841 }
8842 }
8843
8844 // The Nu_mu+e CC cross section in barn well above threshold
8845 Double_t sigma0=pow(fFermi,2.)*fHbarc2*2.e-3*fMe*egev/acos(-1.);
8846
8847 if (mode==-1) // CC xsec
8848 {
8849 if (type>1) fact=fnumucce;
8850 }
8851 if (mode==-2) // NC xsec
8852 {
8853 if (type>1) fact=fnumunce;
8854 if (type<-1) fact=fanumunce;
8855 }
8856 if (mode==-3) // Total xsec
8857 {
8858 if (type==1) fact=fnuetote;
8859 if (type==-1) fact=fanuetote;
8860 if (type>1) fact=fnumucce+fnumunce;
8861 if (type<-1) fact=fanumunce;
8862 }
8863 if (mode==-4 && type==-1) fact=f4;
8864 xsec=fact*sigma0;
8865 }
8866
8867 xsec/=xscale;
8868
8869 return xsec;
8870}
8871
8872Double_t NcAstrolab::GetNeutrinoAngle(Double_t E,TString u,Int_t mode,TF1* f)
8873{
8909
8910 Double_t value=-1;
8911
8912 if (E<=0 || mode<0 || mode>2) return value;
8913
8914 // Convert to TeV
8915 E*=0.001;
8916
8917 // The parametrisation (in degrees) for a 1 TeV neutrino
8918 Double_t mean=1.38711583;
8919 Double_t median=0.86842105;
8920 Double_t mpv=0.560150;
8921 Double_t sigma=0.226679;
8922
8923 // Scaling the parameters to the provided neutrino energy
8924 Double_t p=log10(E);
8925 Double_t scale=1./(pow(1.5,p)*sqrt(E));
8926
8927 mean*=scale;
8928 median*=scale;
8929 mpv*=scale;
8930 sigma*=scale;
8931
8932 // Create a normalized Landau distribution template
8933 if (!fNuAngle)
8934 {
8935 fNuAngle=new TF1("NuAngle","TMath::Landau(x,[0],[1],1)",0,90);
8936 fNuAngle->SetTitle("Landau pdf;Neutrino-lepton opening angle in degrees;PDF");
8937 }
8938
8939 // Set the parameters for the Landau parametrization
8940 fNuAngle->SetParameter(0,mpv);
8941 fNuAngle->SetParameter(1,sigma);
8942
8943 // Obtain an opening angle value according to the pdf
8944 Double_t ang=fNuAngle->GetRandom();
8945
8946 if (u=="rad")
8947 {
8948 Double_t fact=acos(-1.)/180.; // Coversion factor degrees->radians
8949 mean*=fact;
8950 median*=fact;
8951 ang*=fact;
8952 }
8953
8954 // Provide the used pdf if requested
8955 if (f) fNuAngle->Copy(*f);
8956
8957 value=mean;
8958 if (mode==1) value=median;
8959 if (mode==2) value=ang;
8960
8961 return value;
8962}
8963
8964void NcAstrolab::RandomPosition(Nc3Vector& v,Double_t thetamin,Double_t thetamax,Double_t phimin,Double_t phimax)
8965{
8981
8982 // If needed, initialise the randomiser with a "date/time driven" seed
8983 // using the timestamp of the moment of this invokation of the member function.
8984 // This will ensure different random sequences if the user repeats analyses
8985 // with identical measurements and reference signals without explicit initialisation
8986 // of the randomiser by the user at the start of the analysis.
8987 if (!fRan) fRan=new NcRandom(-1);
8988
8989 // Generate random angles in the specified range
8990 Double_t pi=acos(-1.);
8991 Double_t cosmax=cos(thetamin*pi/180.);
8992 Double_t cosmin=cos(thetamax*pi/180.);
8993 Double_t cost=fRan->Uniform(cosmin,cosmax);
8994 Double_t theta=acos(cost)*180./pi;
8995 Double_t phi=fRan->Uniform(phimin,phimax);
8996
8997 Double_t norm=1;
8998 if (v.HasVector()) norm=v.GetNorm();
8999
9000 Double_t err[3]={0,0,0};
9001 Int_t ier=0;
9002 if (v.HasErrors())
9003 {
9004 ier=1;
9005 v.GetErrors(err,"car");
9006 }
9007
9008 v.SetVector(norm,theta,phi,"sph","deg");
9009 if (ier) v.SetErrors(err,"car");
9010}
9011
9013{
9032
9033 if (!v.HasVector()) return;
9034
9035 // If needed, initialise the randomiser with a "date/time driven" seed
9036 // using the timestamp of the moment of this invokation of the member function.
9037 // This will ensure different random sequences if the user repeats analyses
9038 // with identical measurements and reference signals without explicit initialisation
9039 // of the randomiser by the user at the start of the analysis.
9040 if (!fRan) fRan=new NcRandom(-1);
9041
9042 Double_t norm=v.GetX(1,"sph","deg");
9043 Double_t theta=v.GetX(2,"sph","deg");
9044 Double_t phi=v.GetX(3,"sph","deg");
9045 Double_t err[3]={0,0,0};
9046 Int_t ier=0;
9047 if (v.HasErrors())
9048 {
9049 ier=1;
9050 v.GetErrors(err,"car");
9051 }
9052 if (norm<=0)
9053 {
9054 norm=1;
9055 err[0]=0;
9056 }
9057 v.SetVector(norm,theta,phi,"sph","deg");
9058
9059 // The smeared position will be generated as if the actual vector "v" coincided with the positive Z-axis.
9060 // The actual smeared position will be obtained via a "backward rotation" to the real frame orientation.
9061
9062 // Determine the rotation matrix for the frame in which "v" coincides with the positive Z-axis.
9063 TRotMatrix m;
9064 m.SetAngles(90.+theta,phi,90,phi+90.,theta,phi);
9065
9066 // Generate smeared position w.r.t. the fictative Z-axis
9067 Double_t pi=acos(-1.);
9068 Double_t cosmax=1;
9069 Double_t cosmin=cos(fabs(sigma)*pi/180.);
9070 Double_t phimin=0;
9071 Double_t phimax=360;
9072 Double_t cost=0;
9073 if (sigma<0)
9074 {
9075 cost=fRan->Uniform(cosmin,cosmax);
9076 theta=acos(cost)*180./pi;
9077 }
9078 else
9079 {
9080 theta=fRan->Gauss(0.,sigma);
9081 }
9082 phi=fRan->Uniform(phimin,phimax);
9083
9084 // Enter the "fake" smeared position into vector "v".
9085 v.SetVector(norm,theta,phi,"sph","deg");
9086
9087 // Invoke the inverse rotation to obtain the actual smeared position.
9088 v=v.GetUnprimed(&m);
9089 if (ier) v.SetErrors(err,"car");
9090}
9091
9093{
9110
9111 if (!v.HasVector()) return;
9112
9113 // If needed, initialise the randomiser with a "date/time driven" seed
9114 // using the timestamp of the moment of this invokation of the member function.
9115 // This will ensure different random sequences if the user repeats analyses
9116 // under identical conditions without explicit initialisation of the randomiser
9117 // by the user at the start of the analysis.
9118 if (!fRan) fRan=new NcRandom(-1);
9119
9120 Double_t norm=v.GetX(1,"sph","deg");
9121 Double_t theta=v.GetX(2,"sph","deg");
9122 Double_t phi=v.GetX(3,"sph","deg");
9123 Double_t err[3]={0,0,0};
9124 Int_t ier=0;
9125 if (v.HasErrors())
9126 {
9127 ier=1;
9128 v.GetErrors(err,"car");
9129 }
9130 if (norm<=0)
9131 {
9132 norm=1;
9133 err[0]=0;
9134 }
9135 v.SetVector(norm,theta,phi,"sph","deg");
9136
9137 // The shifted position will be generated as if the actual vector "v" coincided with the positive Z-axis.
9138 // The actual shifted position will be obtained via a "backward rotation" to the real frame orientation.
9139
9140 // Determine the rotation matrix for the frame in which "v" coincides with the positive Z-axis.
9141 TRotMatrix m;
9142 m.SetAngles(90.+theta,phi,90,phi+90.,theta,phi);
9143
9144 // Generate the shifted position w.r.t. the fictative Z-axis
9145 Double_t phimin=0;
9146 Double_t phimax=360;
9147 theta=angle;
9148 phi=fRan->Uniform(phimin,phimax);
9149
9150 // Enter the "fake" shifted position into vector "v".
9151 v.SetVector(norm,theta,phi,"sph","deg");
9152
9153 // Invoke the inverse rotation to obtain the actual shifted position.
9154 v=v.GetUnprimed(&m);
9155 if (ier) v.SetErrors(err,"car");
9156}
9157
9158TH1F NcAstrolab::GetDxHistogram(TH1* hx,Int_t nc,Double_t dxbin,Double_t dxmin,Double_t dxmax,Int_t mode,Double_t fact)
9159{
9257
9258 TH1F hdx;
9259
9260 if (mode<0 || mode>3) return hdx;
9261
9262 if (!hx) return hdx;
9263
9264 if (nc<1) return hdx;
9265
9266 Int_t nenhx=hx->GetEntries();
9267 if (nenhx<=nc) return hdx;
9268
9269 Int_t idxbin=TMath::Nint(dxbin);
9270 if (idxbin<-2) return hdx;
9271
9272 // Create the output histogram if all parameters have been specified or determined automatically.
9273 // If not, this will be done at a recursive invokation (see below) once (some of) the
9274 // parameters have been determined automatically from the input histogram.
9275 if (dxmin>=0 && dxmax>=dxmin && dxbin>0)
9276 {
9277 Int_t nbins=1;
9278 Double_t range=dxmax-dxmin;
9279 if (range>dxbin) nbins=TMath::Nint(range/dxbin);
9280 hdx.SetBins(nbins,dxmin,dxmax);
9281
9282 // Add histogram and axes titles
9283 TString s;
9284 Double_t binwidth=hdx.GetXaxis()->GetBinWidth(1);
9285 s.Form("Dx interval distribution between %-i consecutive entries (nc=%-i, mode=%-i);Dx interval;Counts per bin of size %-.3g",nc+1,nc,mode,binwidth);
9286 hdx.SetNameTitle("DxHistogram",s);
9287 }
9288
9289 // If needed, initialise the randomiser with a "date/time driven" seed
9290 // using the timestamp of the moment of this invokation of the member function.
9291 // This will ensure different random sequences if the user repeats analyses
9292 // under identical conditions without explicit initialisation of the randomiser
9293 // by the user at the start of the analysis.
9294 if (!fRan) fRan=new NcRandom(-1);
9295
9296 // Determine the minimum and maximum encountered dx or fill the output histogram
9297 Double_t x1,x2,deltax;
9298 Int_t nx1,nx2;
9299 Double_t deltaxmin=0;
9300 Double_t deltaxmax=0;
9301 Bool_t found=kFALSE;
9302 Int_t ndxcount=0;
9303 Int_t jstart;
9304
9305 Int_t nbhx=hx->GetNbinsX();
9306 Double_t value=0;
9307 Double_t xlow=0;
9308 Double_t xup=0;
9309 Double_t bsize=0;
9310 for (Int_t i=1; i<=nbhx; i++)
9311 {
9312 deltax=-1;
9313 ndxcount=0;
9314 xlow=hx->GetBinLowEdge(i);
9315 bsize=hx->GetBinWidth(i);
9316 xup=xlow+bsize;
9317 x1=hx->GetBinCenter(i);
9318 if (mode==1 || mode==3) x1=fRan->Uniform(xlow,xup);
9319 value=hx->GetBinContent(i);
9320 nx1=0;
9321 if (value) nx1=1;
9322 if (mode<2) nx1=TMath::Nint(value);
9323
9324 while (nx1>0)
9325 {
9326 // Check for multiple counts (left) in this bin
9327 jstart=i+1;
9328 if (nx1>1) jstart=i;
9329
9330 for (Int_t j=jstart; j<=nbhx; j++)
9331 {
9332 xlow=hx->GetBinLowEdge(j);
9333 bsize=hx->GetBinWidth(j);
9334 xup=xlow+bsize;
9335 x2=hx->GetBinCenter(j);
9336 if (mode==1 || mode==3) x2=fRan->Uniform(xlow,xup);
9337 value=hx->GetBinContent(j);
9338 nx2=0;
9339 if (value) nx2=1;
9340 if (mode<2) nx2=TMath::Nint(value);
9341
9342 if (j==i) nx2=nx1-1; // Counting within the same bin
9343
9344 // Empty bin
9345 if (nx2<1) continue;
9346
9347 ndxcount+=nx2;
9348
9349 if (ndxcount>=nc)
9350 {
9351 deltax=fabs(x2-x1);
9352 if (dxmin>=0 && dxmax>=dxmin && dxbin>0) // Output histogram has been initialised
9353 {
9354 hdx.Fill(deltax);
9355 }
9356 else // Auto-determination of the output histogram range
9357 {
9358 if (!found || deltax<deltaxmin) deltaxmin=deltax;
9359 if (!found || deltax>deltaxmax) deltaxmax=deltax;
9360 }
9361 ndxcount=0;
9362 found=kTRUE;
9363 break;
9364 }
9365 }
9366 nx1--;
9367 }
9368 }
9369
9370 // Check if a suitable configuration of entries was encountered
9371 if (!found) return hdx;
9372
9373 // Check if a recursive call is needed to actually create and fill the output histogram
9374 Int_t nen=hdx.GetEntries();
9375 if (!nen)
9376 {
9377 // Set the bin size (if needed) for the output histogram
9378 if (!idxbin && dxbin<=0) dxbin=hx->GetBinWidth(1);
9379 if (idxbin==-1)
9380 {
9381 dxbin=(hx->GetBinWidth(1))*fact;
9382 if (deltaxmin>0 && deltaxmin>dxbin) dxbin=deltaxmin;
9383 if (dxbin<=0) dxbin=hx->GetBinWidth(1);
9384 }
9385 if (idxbin==-2)
9386 {
9387 dxbin=hx->GetBinWidth(1);
9388 dxbin=dxbin*float(nc);
9389 }
9390
9391 // Set the auto-determined range of the output histogram
9392 if (dxmin<0)
9393 {
9394 dxmin=deltaxmin;
9395 // Compensate for randomized x-values within the input histogram bins
9396 if (mode==1 || mode==3)
9397 {
9398 bsize=hx->GetBinWidth(1);
9399 dxmin=dxmin-2.*bsize;
9400 if (dxmin<0) dxmin=0;
9401 }
9402 }
9403 if (dxmax<0)
9404 {
9405 dxmax=deltaxmax+dxbin;
9406 // Compensate for randomized x-values within the input histogram bins
9407 if (mode==1 || mode==3)
9408 {
9409 bsize=hx->GetBinWidth(1);
9410 dxmax=dxmax+2.*bsize;
9411 }
9412 }
9413
9414 // Invoke the recursive call to create and fill the output histogram
9415 hdx=GetDxHistogram(hx,nc,dxbin,dxmin,dxmax,mode,fact);
9416 }
9417
9418 return hdx;
9419}
9420
9421TH1F NcAstrolab::GetDifHistogram(TH1* hin,Int_t mode,TString s,TF1* f) const
9422{
9457
9458 TH1F hout;
9459
9460 if (!hin) return hout;
9461
9462 Int_t nbins=hin->GetNbinsX();
9463 if (!nbins) return hout;
9464
9465 // Set the X-axis parameters identical to the input histogram
9466 const TArrayD* xarr=hin->GetXaxis()->GetXbins();
9467 Int_t xsize=xarr->GetSize();
9468 if (!xsize)
9469 {
9470 Double_t xmin=hin->GetXaxis()->GetXmin();
9471 Double_t xmax=hin->GetXaxis()->GetXmax();
9472 hout.SetBins(nbins,xmin,xmax);
9473 }
9474 else
9475 {
9476 const Double_t* xbins=xarr->GetArray();
9477 hout.SetBins(nbins,xbins);
9478 }
9479
9480 // Set histogram title
9481 hout.SetNameTitle("DifHistogram",hin->GetTitle());
9482
9483 // Set axes titles
9484 TString sxin=hin->GetXaxis()->GetTitle();
9485 TString syin=hin->GetYaxis()->GetTitle();
9486
9487 TString sxout=sxin;
9488
9489 TString syout=s;
9490 if (syout=="")
9491 {
9492 if (f)
9493 {
9494 syout=f->GetExpFormula("p");
9495 syout+="*";
9496 }
9497 syout+="d(";
9498 syout+=syin;
9499 syout+=")/d(";
9500
9501 // Remove Log indication from the "hin" X-axis title
9502 // to get a proper dy/dx label for the "hout" Y-axis
9503 if (mode)
9504 {
9505 sxin.ReplaceAll("^{10}log","");
9506 sxin.ReplaceAll("^{10}Log","");
9507 sxin.ReplaceAll("log10","");
9508 sxin.ReplaceAll("Log10","");
9509 sxin.ReplaceAll("log","");
9510 sxin.ReplaceAll("Log","");
9511 sxin.ReplaceAll("ln","");
9512 sxin.ReplaceAll("Ln","");
9513 }
9514
9515 syout+=sxin;
9516 syout+=")";
9517 syout.ReplaceAll("((","(");
9518 syout.ReplaceAll("))",")");
9519 }
9520
9521 hout.GetXaxis()->SetTitle(sxout.Data());
9522 hout.GetYaxis()->SetTitle(syout.Data());
9523
9524 // Determine the new Y-values and fill the output histogram
9525 Double_t x=0;
9526 Double_t y=0;
9527 Double_t err=0;
9528 Double_t width=0;
9529 Double_t binlow=0;
9530 Double_t binup=0;
9531 Double_t scale=0;
9532 for (Int_t i=1; i<=nbins; i++)
9533 {
9534 x=hin->GetBinCenter(i);
9535 y=hin->GetBinContent(i);
9536 err=fabs(hin->GetBinError(i));
9537 width=hin->GetBinWidth(i);
9538 binlow=hin->GetBinLowEdge(i);
9539 binup=binlow+width;
9540
9541 // Check if the binwidth is physical
9542 if (width<=0) continue;
9543
9544 // Correct for log-scale annotation on X-axis
9545 if (mode==1)
9546 {
9547 x=pow(10.,x);
9548 width=pow(10.,binup)-pow(10.,binlow);
9549 }
9550 if (mode==2)
9551 {
9552 x=exp(x);
9553 width=exp(binup)-exp(binlow);
9554 }
9555
9556 y=y/width;
9557 err=err/width;
9558
9559 // Rescale via the function "f" if provided
9560 if (f)
9561 {
9562 scale=f->Eval(x);
9563 y=y*scale;
9564 err=err*scale;
9565 }
9566
9567 hout.SetBinContent(i,y);
9568 hout.SetBinError(i,err);
9569 }
9570
9571 return hout;
9572}
9573
9574TH1F NcAstrolab::GetCountsHistogram(TF1& spec,Int_t nbins,Double_t xmin,Double_t xmax,Int_t mode,TString s) const
9575{
9601
9602 // Setting up the output histogram
9603 TH1F hout;
9604 hout.SetName("CountsHistogram");
9605
9606 // Set histogram title and axes labels
9607 if (s=="")
9608 {
9609 s="CountsHistogram;";
9610 if (mode==1)
9611 {
9612 s+="^{10}Log(";
9613 }
9614 else if (mode==2)
9615 {
9616 s+="Ln(";
9617 }
9618 s+=spec.GetXaxis()->GetTitle();
9619 if (mode) s+=")";
9620 s+=";Counts";
9621 }
9622 hout.SetTitle(s);
9623
9624 // Setting histogram binning
9625 Double_t step=(xmax-xmin)/double(nbins);
9626 Double_t* xbins=new Double_t[nbins+1];
9627 Double_t x=xmin;
9628 for (Int_t ibin=0; ibin<=nbins; ibin++)
9629 {
9630 xbins[ibin]=x;
9631 x=x+step;
9632 }
9633
9634 hout.SetBins(nbins,xbins);
9635
9636 // Filling the output histogram
9637 Double_t xlow=0;
9638 Double_t xup=0;
9639 Double_t N=0;
9640 x=xmin;
9641 for (Int_t ibin=1; ibin<=nbins; ibin++)
9642 {
9643 if (!mode)
9644 {
9645 xlow=xbins[ibin-1];
9646 xup=xbins[ibin];
9647 }
9648 else if (mode==1)
9649 {
9650 xlow=pow(10,xbins[ibin-1]);
9651 xup=pow(10,xbins[ibin]);
9652 }
9653 else if (mode==2)
9654 {
9655 xlow=exp(xbins[ibin-1]);
9656 xup=exp(xbins[ibin]);
9657 }
9658
9659 N=spec.Integral(xlow,xup);
9660 hout.Fill(x,N);
9661 x=x+step;
9662 }
9663
9664 delete [] xbins;
9665
9666 return hout;
9667}
9668
9669TH1F NcAstrolab::GetCountsHistogram(TH1& hin,Int_t mode,TString s,TF1* fscale) const
9670{
9699
9700 // Setting up the output histogram
9701 TH1F hout;
9702 hout.SetName("CountsHistogram");
9703 Int_t nbins=hin.GetNbinsX();
9704
9705 if (nbins<1) return hout;
9706
9707 TAxis* ax=hin.GetXaxis();
9708 Double_t xmin=ax->GetXmin();
9709 Double_t xmax=ax->GetXmax();
9710 hout.SetBins(nbins,xmin,xmax);
9711
9712 // Set histogram title and axes labels
9713 if (s=="")
9714 {
9715 s=hin.GetTitle();
9716 s+=";";
9717 TString tx=ax->GetTitle();
9718 if (tx!="")
9719 {
9720 s+=tx;
9721 }
9722 else
9723 {
9724 if (mode==0) s+="x";
9725 if (mode==1) s+="^{10}Log(x)";
9726 if (mode==2) s+="Ln(x)";
9727 }
9728 s+=";Counts";
9729 }
9730 hout.SetTitle(s);
9731
9732 // Filling the output histogram
9733 Double_t x=0;
9734 Double_t xlow=0;
9735 Double_t xup=0;
9736 Double_t dx=0;
9737 Double_t xval=0;
9738 Double_t N=0;
9739 Double_t fval=0;
9740 for (Int_t ibin=1; ibin<=nbins; ibin++)
9741 {
9742 x=hin.GetBinCenter(ibin);
9743 xlow=hin.GetBinLowEdge(ibin);
9744 xup=xlow+hin.GetBinWidth(ibin);
9745 N=hin.GetBinContent(ibin);
9746 if (!mode)
9747 {
9748 xval=x;
9749 dx=xup-xlow;
9750 N=N*dx;
9751 }
9752 else if (mode==1)
9753 {
9754 xval=pow(10,x);
9755 dx=pow(10,xup)-pow(10,xlow);
9756 N=N*dx;
9757 }
9758 else if (mode==2)
9759 {
9760 xval=exp(x);
9761 dx=exp(xup)-exp(xlow);
9762 N=N*dx;
9763 }
9764
9765 // Compensate for the Y-axis scaling if needed
9766 if (fscale)
9767 {
9768 fval=fscale->Eval(xval);
9769 if (fval) N=N/fval;
9770 }
9771
9772 hout.Fill(x,N);
9773 }
9774
9775 return hout;
9776}
9777
9778TH1F NcAstrolab::GetLogHistogram(TH1* hin,Int_t mode,TString s) const
9779{
9799
9800 TH1F hout;
9801
9802 if (!hin || mode<1 || mode>2) return hout;
9803
9804 Int_t nbins=hin->GetNbinsX();
9805 if (!nbins) return hout;
9806
9807 // Set the X-axis parameters identical to the input histogram
9808 const TArrayD* xarr=hin->GetXaxis()->GetXbins();
9809 Int_t xsize=xarr->GetSize();
9810 if (!xsize)
9811 {
9812 Double_t xmin=hin->GetXaxis()->GetXmin();
9813 Double_t xmax=hin->GetXaxis()->GetXmax();
9814 hout.SetBins(nbins,xmin,xmax);
9815 }
9816 else
9817 {
9818 const Double_t* xbins=xarr->GetArray();
9819 hout.SetBins(nbins,xbins);
9820 }
9821
9822 // Set histogram and axes titles
9823 hout.SetNameTitle("LogHistogram",hin->GetTitle());
9824
9825 if (s=="")
9826 {
9827 s="^{10}Log(";
9828 if (mode==2) s="Ln(";
9829 s+=hin->GetYaxis()->GetTitle();
9830 s+=")";
9831 }
9832
9833 hout.GetXaxis()->SetTitle(hin->GetXaxis()->GetTitle());
9834 hout.GetYaxis()->SetTitle(s.Data());
9835
9836 // Determine the new Y-values and fill the output histogram
9837 Double_t y=0;
9838 Double_t err=0;
9839 Double_t yplus=0;
9840 for (Int_t i=1; i<=nbins; i++)
9841 {
9842 y=hin->GetBinContent(i);
9843 err=fabs(hin->GetBinError(i));
9844 yplus=y+err;
9845
9846 // Check if Log10(y) or Ln(y) is defined
9847 if (y<=0) continue;
9848
9849 if (mode==1)
9850 {
9851 y=log10(y);
9852 yplus=log10(yplus);
9853 }
9854 else
9855 {
9856 y=log(y);
9857 yplus=log(yplus);
9858 }
9859
9860 hout.SetBinContent(i,y);
9861 err=fabs(yplus-y);
9862 hout.SetBinError(i,err);
9863 }
9864
9865 return hout;
9866}
9867
9868Double_t NcAstrolab::GetBackgroundRateProb(Double_t* vars,Double_t* pars)
9869{
9901
9902 Double_t b=vars[0];
9903 Int_t Noff=int(pars[0]);
9904 Double_t Toff=pars[1];
9905 Double_t bmax=pars[2];
9906 Double_t prec=pars[3];
9907
9908 if (b<=0 || Noff<0 || Toff<=0) return 0;
9909
9910 Double_t rNoff=Noff;
9911 if (bmax<0) bmax=100.*rNoff/Toff;
9912
9913 NcMath math;
9914
9915 Double_t lnU=0;
9916 Double_t lnD=0;
9917 Double_t lnprob=0;
9918 Double_t prob=0;
9919
9920 // The ln of the numerator of Eq.(15) of the publication mentioned above
9921 lnU=log(Toff)+rNoff*log(b*Toff)-b*Toff;
9922
9923 // The ln of the denominator of eq.(15) of the publication mentioned above
9924 lnD=math.LnGamma(Noff+1,bmax*Toff,1);
9925
9926 lnprob=lnU-lnD;
9927
9928 if (lnprob < -fabs(prec)) return 0;
9929
9930 if (lnprob > fabs(prec)) lnprob=fabs(prec);
9931 prob=exp(lnprob);
9932
9933 return prob;
9934}
9935
9936Double_t NcAstrolab::GetSignalRateProb(Double_t* vars,Double_t* pars)
9937{
9980
9981 Double_t s=vars[0];
9982 Int_t Non=TMath::Nint(pars[0]);
9983 Double_t Ton=pars[1];
9984 Int_t Noff=TMath::Nint(pars[2]);
9985 Double_t Toff=pars[3];
9986 Double_t smax=pars[4];
9987 Double_t bmax=pars[5];
9988 Double_t prec=pars[6];
9989
9990 if (s<0 || Non<0 || Ton<=0 || Noff<0 || Toff<=0) return 0;
9991
9992 Double_t rNon=Non;
9993 if (smax<0) smax=100.*rNon/Ton;
9994
9995 Double_t rNoff=Noff;
9996 if (bmax<0) bmax=100.*rNoff/Toff;
9997
9998 NcMath math;
9999
10000 //Store factorials in an array to decrease the processing time
10001 Int_t ndim=Non+Noff+1;
10002 TArrayD lnfacN(ndim);
10003
10004 lnfacN[0]=0;
10005 Double_t x=0;
10006 for (Int_t i=1; i<ndim; i++)
10007 {
10008 x+=log(double(i));
10009 lnfacN[i]=x;
10010 }
10011
10012 Double_t lnU=0;
10013 Double_t lnD=0;
10014 Double_t sumU=0;
10015 Double_t sumD=0;
10016 Double_t prob=0;
10017 Double_t gammaP1=0;
10018 Double_t gammaP2=0;
10019 Double_t ri=0;
10020
10021 for(Int_t i=0; i<=Non; i++)
10022 {
10023 ri=i;
10024
10025 // The incomplete gamma functions P(a,x)
10026 gammaP1=math.Gamma(Non+Noff+1-i,bmax*(Ton+Toff),0);
10027 gammaP2=math.Gamma(i+1,smax*Ton,0);
10028
10029 // The ln of the numerator of Eq.(21) of the publication mentioned above normalized by Non!/(Non+Noff)!
10030 lnU=-s*Ton+ri*log(s)+ri*log(Ton+Toff)-lnfacN[i]-lnfacN[Non-i]+lnfacN[Non+Noff-i]-lnfacN[Non+Noff]+lnfacN[Non];
10031
10032 if ((lnU > -fabs(prec)) && (lnU < fabs(prec))) sumU+=exp(lnU)*gammaP1;
10033
10034 //The ln of the denominator of Eq.(21) of the publication mentioned above normalized by Non!/(Non+Noff)!
10035 lnD=ri*log(Ton+Toff)-(ri+1.)*log(Ton)-lnfacN[i]-lnfacN[Non-i]+lnfacN[Non+Noff-i]+lnfacN[i]-lnfacN[Non+Noff]+lnfacN[Non];
10036
10037 if ((lnD > -fabs(prec)) && (lnD < fabs(prec))) sumD+=exp(lnD)*gammaP1*gammaP2;
10038 }
10039
10040 if (sumD) prob=sumU/sumD;
10041
10042 return prob;
10043}
10044
10045TF1 NcAstrolab::GetBackgroundRatePDF(Double_t Noff,Double_t Toff,Double_t bmax,Double_t prec)
10046{
10076
10077 if (bmax<0) bmax=100.*Noff/Toff;
10078
10079 Int_t npar=4;
10080 TF1 pdf("BkgRatePDF",this,&NcAstrolab::GetBackgroundRateProb,0,bmax,npar,"NcAstrolab","GetBackgroundRateProb");
10081
10082 pdf.SetParName(0,"Noff");
10083 pdf.SetParName(1,"Toff");
10084 pdf.SetParName(2,"bmax");
10085 pdf.SetParName(3,"prec");
10086
10087 pdf.SetParameter("Noff",Noff);
10088 pdf.SetParameter("Toff",Toff);
10089 pdf.SetParameter("bmax",bmax);
10090 pdf.SetParameter("prec",prec);
10091
10092 pdf.SetTitle("Bayesian posterior background rate PDF;Background rate B in Hz;p(B|Noff,Toff,I)");
10093 pdf.SetRange(0,bmax);
10094
10095 return pdf;
10096}
10097
10098TF1 NcAstrolab::GetSignalRatePDF(Double_t Non,Double_t Ton,Double_t Noff,Double_t Toff,Double_t Ra,Double_t Re,Double_t smax,Double_t bmax,Double_t prec)
10099{
10137
10138 if (smax<0) smax=100.*Non/Ton;
10139
10140 // Correct the off source observation for different coverage and detection efficiency
10141 // with respect to the actual on source measurement
10142 Noff=Noff*Ra*Re;
10143
10144 if (bmax<0) bmax=100.*Noff/Toff;
10145
10146 Int_t npar=7;
10147 TF1 pdf("SignalRatePDF",this,&NcAstrolab::GetSignalRateProb,0,smax,npar,"NcAstrolab","GetSignalRateProb");
10148
10149 pdf.SetParName(0,"Non");
10150 pdf.SetParName(1,"Ton");
10151 pdf.SetParName(2,"Noff");
10152 pdf.SetParName(3,"Toff");
10153 pdf.SetParName(4,"smax");
10154 pdf.SetParName(5,"bmax");
10155 pdf.SetParName(6,"prec");
10156
10157 pdf.SetParameter("Non",Non);
10158 pdf.SetParameter("Ton",Ton);
10159 pdf.SetParameter("Noff",Noff);
10160 pdf.SetParameter("Toff",Toff);
10161 pdf.SetParameter("smax",smax);
10162 pdf.SetParameter("bmax",bmax);
10163 pdf.SetParameter("prec",prec);
10164
10165 pdf.SetTitle("Bayesian posterior signal rate PDF;Signal rate S in Hz;p(S|Non,Ton,Noff,Toff,I)");
10166 pdf.SetRange(0,smax);
10167
10168 return pdf;
10169}
10170
10171Double_t NcAstrolab::GetUpperLimit(TF1 pdf,Double_t p)
10172{
10189
10190 if (p<=0 || p>100) return 0;
10191
10192 Double_t ua[2];
10193 Double_t xa[2];
10194 Int_t nu=0;
10195 Double_t ul=0;
10196
10197 xa[0]=p/100.;
10198 nu=pdf.GetQuantiles(1,ua,xa);
10199
10200 if (nu) ul=ua[0];
10201
10202 return ul;
10203}
10204
10205Double_t NcAstrolab::GetUpperLimit(TH1* his,Double_t p)
10206{
10216
10217 if (p<=0 || p>100 || !his) return 0;
10218
10219 Double_t ua[2];
10220 Double_t xa[2];
10221 Int_t nu=0;
10222 Double_t ul=0;
10223
10224 // Ensure correct results als for histograms filled via SetBinContent().
10225 his->ComputeIntegral();
10226
10227 xa[0]=p/100.;
10228 nu=his->GetQuantiles(1,ua,xa);
10229
10230 if (nu) ul=ua[0];
10231
10232 return ul;
10233}
10234
10235Double_t NcAstrolab::GetCredibleInterval(TF1 pdf,Double_t p,Double_t& xlow,Double_t& xup,Int_t n)
10236{
10268
10269 xlow=0;
10270 xup=0;
10271
10272 if (p<=0 || p>100 || n<2) return 0;
10273
10274 // Set the precision
10275 Double_t prec=1./double(n);
10276
10277 // Obtain the n quantiles of the PDF
10278 Double_t* q=new Double_t[n];
10279 Double_t* sumq=new Double_t[n];
10280 Double_t sum=0;
10281 for (Int_t i=0; i<n; i++)
10282 {
10283 sumq[i]=sum;
10284 sum+=prec;
10285 }
10286 Int_t ncalc=pdf.GetQuantiles(n,q,sumq);
10287
10288 // More than 1 quantile is needed
10289 if (ncalc<2)
10290 {
10291 delete [] q;
10292 delete [] sumq;
10293 return 0;
10294 }
10295
10296 // Determine the index in the quantiles array q[] corresponding to
10297 // the X coordinate of the mode of the PDF
10298 Double_t xmode=pdf.GetMaximumX();
10299 Int_t imode=0;
10300 Double_t diff,diffmin;
10301 diffmin=fabs(q[ncalc-1]-q[0]);
10302 for (Int_t i=0; i<ncalc; i++)
10303 {
10304 diff=fabs(xmode-q[i]);
10305 if (diff<diffmin)
10306 {
10307 diffmin=diff;
10308 imode=i;
10309 }
10310 }
10311
10312 // Get the total integral over the quantiles range of the PDF
10313 Double_t xmin=q[0];
10314 Double_t xmax=q[ncalc-1];
10315 Double_t totint=pdf.Integral(xmin,xmax);
10316
10317 // The PDF should have a total integral >0
10318 if (totint<=0)
10319 {
10320 delete [] q;
10321 delete [] sumq;
10322 return 0;
10323 }
10324
10325 // Determine the requested credible interval around the mode
10326 Int_t ilow=imode;
10327 Int_t iup=imode;
10328 xlow=q[ilow];
10329 xup=q[iup];
10330 Double_t ylow=pdf.Eval(q[ilow]);
10331 Double_t yup=pdf.Eval(q[iup]);
10332 Double_t frac=p/100.;
10333 if (frac>1) frac=1;
10334 Double_t credint=-1;
10335 while (credint<frac*totint)
10336 {
10337 if (yup>ylow && iup<(ncalc-1)) // Shift the upper bound up
10338 {
10339 iup++;
10340 xup=q[iup];
10341 yup=pdf.Eval(xup);
10342 }
10343 else if (ylow>yup && ilow>0) // Shift the lower bound down
10344 {
10345 ilow--;
10346 xlow=q[ilow];
10347 ylow=pdf.Eval(xlow);
10348 }
10349 else if (iup<(ncalc-1)) // Shift the upper bound up in case yup=ylow
10350 {
10351 iup++;
10352 xup=q[iup];
10353 yup=pdf.Eval(xup);
10354 }
10355 else if (ilow>0) // Shift the lower bound down in case yup=ylow
10356 {
10357 ilow--;
10358 xlow=q[ilow];
10359 ylow=pdf.Eval(xlow);
10360 }
10361 else // No shift in any bound -> stop
10362 {
10363 break;
10364 }
10365 credint=pdf.Integral(xlow,xup);
10366 }
10367
10368 // Normalisation for non-normalised PDF
10369 Double_t intfrac=credint/totint;
10370
10371 delete [] q;
10372 delete [] sumq;
10373
10374 return intfrac;
10375}
10376
10377Double_t NcAstrolab::GetCredibleInterval(TF1 pdf,Double_t p,Float_t& xlow,Float_t& xup,Int_t n)
10378{
10410
10411 Double_t xxl=0;
10412 Double_t xxu=0;
10413 Double_t val=0;
10414
10415 val=GetCredibleInterval(pdf,p,xxl,xxu,n);
10416
10417 xlow=xxl;
10418 xup=xxu;
10419 return val;
10420}
10421
10422Double_t NcAstrolab::GetCredibleInterval(TH1* his,Double_t p,Double_t& xlow,Double_t& xup)
10423{
10445
10446 xlow=0;
10447 xup=0;
10448
10449 if (p<=0 || p>100 || !his) return 0;
10450
10451 Int_t nbins=his->GetNbinsX();
10452
10453 // More than 2 bins are always needed
10454 if (nbins<2) return 0;
10455
10456 // Ensure correct results also for histograms filled via SetBinContent()
10457 his->ComputeIntegral();
10458
10459 // Obtain the quantiles at the end of each bin of the histogram and at the start of the 1st bin
10460 Int_t n=nbins+1;
10461 Double_t* q=new Double_t[n];
10462 Int_t ncalc=his->GetQuantiles(n,q);
10463
10464 // More than 1 quantile is needed
10465 if (ncalc<2)
10466 {
10467 delete [] q;
10468 return 0;
10469 }
10470
10471 // Determine the index in the quantiles array q[] corresponding to
10472 // the X coordinate of the mode of the histogram
10473 Int_t imode=his->GetMaximumBin();
10474
10475 // Get the total integral of the histogram over the quantiles range
10476 Double_t totint=his->Integral(1,ncalc,"width");
10477
10478 // The histogram should have a total integral >0
10479 if (totint<=0)
10480 {
10481 delete [] q;
10482 return 0;
10483 }
10484
10485 // Determine the requested credible interval around the mode
10486 Int_t ilow=imode;
10487 Int_t iup=imode;
10488 xlow=q[ilow];
10489 xup=q[iup];
10490 Double_t ylow=his->GetBinContent(ilow);
10491 Double_t yup=his->GetBinContent(iup);
10492 Double_t frac=p/100.;
10493 if (frac>1) frac=1;
10494 Double_t credint=-1;
10495 while (credint<frac*totint)
10496 {
10497 if (yup>ylow && iup<(ncalc-1)) // Shift the upper bound up
10498 {
10499 iup++;
10500 xup=q[iup];
10501 yup=his->GetBinContent(iup);
10502 }
10503 else if (ylow>yup && ilow>0) // Shift the lower bound down
10504 {
10505 ilow--;
10506 xlow=q[ilow];
10507 ylow=his->GetBinContent(ilow);
10508 }
10509 else if (iup<(ncalc-1)) // Shift the upper bound up in case yup=ylow
10510 {
10511 iup++;
10512 xup=q[iup];
10513 yup=his->GetBinContent(iup);
10514 }
10515 else if (ilow>0) // Shift the lower bound down in case yup=ylow
10516 {
10517 ilow--;
10518 xlow=q[ilow];
10519 ylow=his->GetBinContent(ilow);
10520 }
10521 else // No shift in any bound -> stop
10522 {
10523 break;
10524 }
10525 credint=his->Integral(ilow,iup,"width");
10526 }
10527
10528 // Normalisation for non-normalised PDF
10529 Double_t intfrac=credint/totint;
10530
10531 delete [] q;
10532
10533 return intfrac;
10534}
10535
10536Double_t NcAstrolab::GetCredibleInterval(TH1* his,Double_t p,Float_t& xlow,Float_t& xup)
10537{
10559
10560 Double_t xxl=0;
10561 Double_t xxu=0;
10562 Double_t val=0;
10563
10564 val=GetCredibleInterval(his,p,xxl,xxu);
10565
10566 xlow=xxl;
10567 xup=xxu;
10568 return val;
10569}
10570
10571Double_t NcAstrolab::KolmogorovTest(TString mode,TH1* h1,TH1* h2,TF1* pdf,Double_t nr,TH1F* ksh,Int_t ncut,Double_t* nrx,Int_t mark)
10572{
10665
10666 Double_t value=-1;
10667
10668 if (!mode.Contains("M") && !mode.Contains("K") && !mode.Contains("P")) return -1;
10669 if (mode.Contains("M") && (mode.Contains("K") || mode.Contains("P"))) return -1;
10670 if (mode.Contains("K") && (mode.Contains("M") || mode.Contains("P"))) return -1;
10671 if (mode.Contains("P") && (mode.Contains("M") || mode.Contains("K"))) return -1;
10672
10673 if (!h1) return -1;
10674 if (!h2 && !pdf) return -1;
10675 if (h2 && pdf) return -1;
10676
10677 ULong64_t nrep=ULong64_t(nr);
10678 ULong64_t jrep;
10679 if (!nrep)
10680 {
10681 if (ncut)
10682 {
10683 nrep=ULong64_t(1.e19);
10684 }
10685 else
10686 {
10687 return -1;
10688 }
10689 }
10690
10691 TAxis* xaxis=h1->GetXaxis();
10692 Double_t xmin1=xaxis->GetXmin();
10693 Double_t xmax1=xaxis->GetXmax();
10694 Double_t range1=xmax1-xmin1;
10695 Int_t nbins1=h1->GetNbinsX();
10696 Double_t nen1=h1->GetSumOfWeights();
10697 Double_t underflow1=h1->GetBinContent(0);
10698 Double_t overflow1=h1->GetBinContent(nbins1+1);
10699 if (mode.Contains("U")) nen1=nen1+underflow1;
10700 if (mode.Contains("O")) nen1=nen1+overflow1;
10701
10702 if (nbins1<=0 || nen1<=0 || range1<=0)
10703 {
10704 cout << " *" << ClassName() << "::KolmogorovTest* Histogram h1 is empty or has inconsistent data." << endl;
10705 cout << " h1 : nentries=" << nen1 << " nbins=" << nbins1 << " xmin=" << xmin1 << " xmax=" << xmax1 << endl;
10706 return -1;
10707 }
10708
10709 if (h2)
10710 {
10711 xaxis=h2->GetXaxis();
10712 Double_t xmin2=xaxis->GetXmin();
10713 Double_t xmax2=xaxis->GetXmax();
10714 Double_t range2=xmax2-xmin2;
10715 Int_t nbins2=h2->GetNbinsX();
10716 Double_t nen2=h2->GetSumOfWeights();
10717
10718 if (nen2<=0 || range2<=0)
10719 {
10720 cout << " *" << ClassName() << "::KolmogorovTest* Histogram h2 is empty or has inconsistent data." << endl;
10721 cout << " h2 : nentries=" << nen2 << " nbins=" << nbins2 << " xmin=" << xmin2 << " xmax=" << xmax2 << endl;
10722 return -1;
10723 }
10724
10725 Double_t prec=1e-6;
10726 if (nbins2!=nbins1 || fabs(xmin2-xmin1)>prec || fabs(xmax2-xmax1)>prec)
10727 {
10728 cout << " *" << ClassName() << "::KolmogorovTest* Histograms h1 and h2 do not have the same binning." << endl;
10729 cout << " h1 : nbins=" << nbins1 << " xmin=" << xmin1 << " xmax=" << xmax1 << endl;
10730 cout << " h2 : nbins=" << nbins2 << " xmin=" << xmin2 << " xmax=" << xmax2 << endl;
10731 return -1;
10732 }
10733 }
10734
10735 // Create the "h2" histogram from the "pdf" function to perform the KS test
10736 if (pdf)
10737 {
10738 pdf->SetRange(xmin1,xmax1);
10739 pdf->SetNpx(nbins1);
10740 h2=(TH1*)pdf->GetHistogram()->Clone();
10741 h2->SetName("hpdf");
10742 // Set all bin errors (incl. underflow and overflow bins) to zero
10743 for (Int_t i=0; i<=nbins1+1; i++)
10744 {
10745 h2->SetBinError(i,0);
10746 }
10747 }
10748
10749 // Convert "mode" into the corresponding character string for TH1::KolmogorovTest
10750 TString s="";
10751 if (mode.Contains("U")) s+="U";
10752 if (mode.Contains("O")) s+="O";
10753 if (mode.Contains("N") && !pdf) s+="N";
10754
10755 // Obtain the maximum KS distance (d0) for the input histogram "h1"
10756 TString s2=s;
10757 s2+="M";
10758 Double_t d0=h2->KolmogorovTest(h1,s2.Data());
10759
10760 // Complete "mode" conversion
10761 if (mode.Contains("M")) s+="M";
10762 if (mode.Contains("I")) s+="D";
10763
10764 // Perform the requested KS test
10765 if (mode.Contains("I"))
10766 {
10767 if (pdf)
10768 {
10769 cout << " *" << ClassName() << "::KolmogorovTest* Single sample KS-test results for execution mode "<< mode.Data() << endl;
10770 if (mode.Contains("N")) cout << " === For a single sample KS-test the mode=N is suppressed ===" << endl;
10771 }
10772 else
10773 {
10774 cout << " *" << ClassName() << "::KolmogorovTest* Two sample KS-test results for execution mode "<< mode.Data() << endl;
10775 }
10776 }
10777 value=h1->KolmogorovTest(h2,s.Data());
10778
10779 // Perform the pseudo experiments, if requested
10780 if (ksh) ksh->SetBins(101,0,1.01);
10781 Double_t xval=0;
10782 Double_t dist=0;
10783 Double_t sumrep=0;
10784 Int_t sumd=0;
10785 TH1* htemp=0;
10786 if (mode.Contains("P"))
10787 {
10788 htemp=(TH1*)h1->Clone();
10789 for (jrep=0; jrep<nrep; jrep++) // Loop of pseudo experiments
10790 {
10791 htemp->Reset();
10792 for (Int_t ien=0; ien<nen1; ien++) // Take the random entries from the reference distribution
10793 {
10794 xval=h2->GetRandom();
10795 htemp->Fill(xval);
10796 }
10797 dist=htemp->KolmogorovTest(h2,s2.Data());
10798 if (ksh) ksh->Fill(dist);
10799 sumrep+=1;
10800 if (dist>=d0) sumd++;
10801
10802 // Stop the pseudo experiments if the required precision is reached
10803 if (ncut && sumd>=ncut) break;
10804
10805 } // end loop over pseudo experiments
10806 value=double(sumd)/sumrep;
10807 if (nrx) *nrx=sumrep;
10808 if (mode.Contains("I"))
10809 {
10810 cout << " P-value = " << value << " after " << sumrep << " pseudo experiments." << endl;
10811 }
10812 }
10813
10814 if (mode.Contains("I")) cout << " Returned value = " << value << endl;
10815
10816 // Complete the attributes for the "ksh" histogram
10817 if (ksh)
10818 {
10819 TString xlabel="Dmax";
10820 TString ylabel="Counts after ";
10821 ylabel+=sumrep;
10822 ylabel+=" pseudo experiments";
10823
10824 ksh->SetTitle("KS-test Dmax distribution from pseudo experiments");
10825 ksh->SetXTitle(xlabel.Data());
10826 ksh->SetYTitle(ylabel.Data());
10827
10828 // Mark the actually observed D0 value by a vertical line in the "ksh" histogram
10829 // Also the corresponding P-value is mentioned in the legend
10830 if (mark)
10831 {
10832 Float_t x=d0;
10833 Float_t ymin=0;
10834 Float_t ymax=ksh->GetMaximum();
10835
10836 TLine* vline=new TLine(x,ymin,x,ymax);
10837 vline->SetLineStyle(2); // Dashed line
10838 vline->SetLineWidth(2);
10839 vline->SetLineColor(4); // Blue color
10840
10841 TString title="P-value : %-10.3g";
10842 TString sh=title.Format(title.Data(),value);
10843
10844 TLegend* leg=new TLegend(0.6,0.8,0.8,0.9);
10845 leg->SetFillColor(0);
10846 leg->SetHeader(sh.Data());
10847 leg->AddEntry(vline,"Observed Dmax","L");
10848
10849 TList* hlist=ksh->GetListOfFunctions();
10850 hlist->Add(vline);
10851 hlist->Add(leg);
10852 }
10853 }
10854
10855 // Delete temporary histograms, if any
10856 if (pdf && h2)
10857 {
10858 delete h2;
10859 h2=0;
10860 }
10861
10862 if (htemp) delete htemp;
10863
10864 return value;
10865}
10866
10867TH1F NcAstrolab::GetCumulHistogram(TH1* h,TString name,TString mode) const
10868{
10895
10896 TH1F hcd;
10897 TString title="Cumulative Distribution of histogram ";
10898 hcd.SetNameTitle(name.Data(),title.Data());
10899
10900 if (!h) return hcd;
10901
10902 TAxis* xaxis=h->GetXaxis();
10903 TAxis* yaxis=h->GetYaxis();
10904 Double_t xmin=xaxis->GetXmin();
10905 Double_t xmax=xaxis->GetXmax();
10906 Double_t range=xmax-xmin;
10907 Int_t nbins=h->GetNbinsX();
10908 Double_t nen=h->GetSumOfWeights();
10909 TString nameh=h->GetName();
10910 TString xtitle=xaxis->GetTitle();
10911 TString ytitle=yaxis->GetTitle();
10912 title+=nameh;
10913 hcd.SetNameTitle(name.Data(),title.Data());
10914 hcd.SetXTitle(xtitle.Data());
10915 hcd.SetYTitle(ytitle.Data());
10916
10917 if (nbins<=0 || nen<=0 || range<=0) return hcd;
10918
10919 if(!(mode.Contains("F") || mode.Contains("B")) || (mode.Contains("F") && mode.Contains("B"))) return hcd;
10920
10921 hcd.SetBins(nbins,xmin,xmax);
10922 title="";
10923 if (mode.Contains("N")) title="Normalized ";
10924 if (mode.Contains("F")) title+="Forward ";
10925 if (mode.Contains("B")) title+="Backward ";
10926 title+="Cumulative Distribution of histogram ";
10927 title+=nameh;
10928 hcd.SetNameTitle(name.Data(),title.Data());
10929 hcd.SetXTitle(xtitle.Data());
10930 hcd.SetYTitle(ytitle.Data());
10931
10932 Double_t norm=1;
10933 if (mode.Contains("N")) norm=nen;
10934 Double_t y=0;
10935 Double_t sum=0;
10936
10937 if (mode.Contains("F")) // Forward cumulation
10938 {
10939 for (Int_t ibin=1; ibin<=nbins; ibin++)
10940 {
10941 y=h->GetBinContent(ibin);
10942 sum+=y/norm;
10943 hcd.SetBinContent(ibin,sum);
10944 }
10945 }
10946 else // Backward cumulation
10947 {
10948 for (Int_t ibin=nbins; ibin>=1; ibin--)
10949 {
10950 y=h->GetBinContent(ibin);
10951 sum+=y/norm;
10952 hcd.SetBinContent(ibin,sum);
10953 }
10954 }
10955 return hcd;
10956}
10957
10958TH1F NcAstrolab::GetCumulHistogram(TF1* f,TString name,Int_t nbins,Double_t xmin,Double_t xmax,TString mode) const
10959{
10987
10988 TH1F hcd;
10989 TString title="Cumulative Distribution Histogram of function ";
10990 hcd.SetNameTitle(name.Data(),title.Data());
10991
10992 if (!f) return hcd;
10993
10994 // The original range of the function "f"
10995 Double_t xminold=f->GetXmin();
10996 Double_t xmaxold=f->GetXmax();
10997
10998 f->SetRange(xmin,xmax);
10999 f->SetNpx(nbins);
11000 TH1* hf=(TH1*)f->GetHistogram();
11001
11002 hcd=GetCumulHistogram(hf,name,mode);
11003
11004 if (hcd.GetEntries()>0) // Histogram has been filled
11005 {
11006 title="";
11007 if (mode.Contains("N")) title="Normalized ";
11008 if (mode.Contains("F")) title+="Forward ";
11009 if (mode.Contains("B")) title+="Backward ";
11010 title+="Cumulative Distribution Histogram of function ";
11011 }
11012
11013 TString namef=f->GetName();
11014 title+=namef;
11015
11016 hcd.SetTitle(title.Data());
11017
11018 // Restore the original range for the function "f"
11019 f->SetRange(xminold,xmaxold);
11020
11021 return hcd;
11022}
11023
11024void NcAstrolab::InitDataNames(Int_t dir,TString frame,TString mode)
11025{
11052
11053 if (!dir || (frame!="equ" && frame!="gal" && frame!="ecl" && frame!="hor" && frame!="icr" && frame!="loc") ||
11054 (mode!="M" && mode!="T" && mode!="B" && mode!="J"))
11055 {
11056 cout << endl;
11057 cout << " *" << ClassName() << "::InitDataNames* Invalid input encountered." << endl;
11058 cout << " dir=" << dir << " frame=" << frame << " mode=" << mode << endl;
11059 return;
11060 }
11061
11062 fDataDir=dir;
11063 fDataFrame=frame;
11064 fDataMode=mode;
11065
11066 // Reset the correspondence table
11067 fDataNames.Reset();
11068
11069 TString sdir="arrival";
11070 if (dir<0) sdir="moving";
11071
11072 if (frame=="equ")
11073 {
11074 if (mode=="M") frame="mean";
11075 if (mode=="T") frame="true";
11076 if (mode=="B") frame="B1950";
11077 if (mode=="J") frame="J2000";
11078 frame+=" equatorial";
11079 }
11080 if (frame=="gal") frame="galactic";
11081 if (frame=="ecl") frame="ecliptic";
11082 if (frame=="hor") frame="horizontal";
11083 if (frame=="icr") frame="ICRS";
11084 if (frame=="loc") frame="local";
11085
11086 cout << endl;
11087 cout << " *" << ClassName() << "::InitDataNames* Prepared for input of " << sdir << " directions in " << frame << " coordinates." << endl;
11088 cout << endl;
11089}
11090
11091void NcAstrolab::SetDataNames(TString obsname,TString varname,TString units,TString func)
11092{
11179
11180 Bool_t error=kFALSE;
11181
11182 if (obsname!="Name" && obsname!="Run" && obsname!="Event" && obsname!="Eventb" && obsname!="VetoLevel"
11183 && obsname!="DetId" && obsname!="Date" && obsname!="Tobs" && obsname!="Tstart" && obsname!="Tend"
11184 && obsname!="d" && obsname!="a" && obsname!="b" && obsname!="z"
11185 && obsname!="E" && obsname!="L" && obsname!="S" && obsname!="F" && obsname!="I" && obsname!="J"
11186 && obsname!="T90" && obsname!="T100"
11187 && obsname!="dsigma" && obsname!="csigma" && obsname!="zsigma"
11188 && obsname!="Esigma" && obsname!="Lsigma" && obsname!="Ssigma" && obsname!="Fsigma" && obsname!="Isigma"
11189 && obsname!="T90sigma" && obsname!="T100sigma") error=kTRUE;
11190 if (obsname=="Date" && (units!="ddmmyyyy" && units!="yyyymmdd" && units!="mmddyyyy" && units!="yyyyddmm")) error=kTRUE;
11191 if ((obsname=="Tobs" || obsname=="Tstart" || obsname=="Tend")
11192 && (units!="JD" && units!="MJD" && units!="TJD" && units!="hms" && units!="hrs")) error=kTRUE;
11193 if ((obsname=="a" || obsname=="b" || obsname=="csigma")
11194 && (units!="rad" && units!="deg" && units!="dms" && units!="hms" && units!="hrs")) error=kTRUE;
11195 if (func!="none" && func!="Log" && func!="Ln") error=kTRUE;
11196
11197 if (error)
11198 {
11199 cout << " *" << ClassName() << "::SetDataNames* Invalid input encountered." << endl;
11200 cout << " obsname=" << obsname << " units=" << units << " func=" << func << endl;
11201 return;
11202 }
11203
11204 Int_t n=fDataNames.GetMaxRow();
11205 TObjString* obs=new TObjString(obsname);
11206 TObjString* var=new TObjString(varname);
11207 TObjString* u=new TObjString(units);
11208 TObjString* f=new TObjString(func);
11209 TObjString* val=new TObjString(""); // Value will be filled in LoadInputData()
11210
11211 fDataNames.EnterObject(n+1,1,obs);
11212 fDataNames.EnterObject(n+1,2,var);
11213 fDataNames.EnterObject(n+1,3,u);
11214 fDataNames.EnterObject(n+1,4,f);
11215 fDataNames.EnterObject(n+1,5,val);
11216}
11217
11219{
11226
11227 TString sdir="undefined";
11228 if (fDataDir>0) sdir="arrival";
11229 if (fDataDir<0) sdir="moving";
11230
11231 TString frame="undefined";
11232 if (fDataFrame=="equ")
11233 {
11234 if (fDataMode=="M") frame="mean";
11235 if (fDataMode=="T") frame="true";
11236 if (fDataMode=="B") frame="B1950";
11237 if (fDataMode=="J") frame="J2000";
11238 frame+=" equatorial";
11239 }
11240 if (fDataFrame=="gal") frame="galactic";
11241 if (fDataFrame=="ecl") frame="ecliptic";
11242 if (fDataFrame=="hor") frame="horizontal";
11243 if (fDataFrame=="icr") frame="ICRS";
11244 if (fDataFrame=="loc") frame="local";
11245
11246 cout << endl;
11247 cout << " *" << ClassName() << "::ListDataNames* Settings for input of " << sdir << " directions in " << frame << " coordinates." << endl;
11248
11249 Int_t n=fDataNames.GetMaxRow();
11250
11251 if (n<1)
11252 {
11253 cout << " *** No settings were specified ***" << endl;
11254 }
11255 else
11256 {
11257 cout << " *** The following " << n << " settings were specified ***" << endl;
11258 }
11259
11260 TObjString* obs=0;
11261 TObjString* var=0;
11262 TObjString* u=0;
11263 TObjString* f=0;
11264 for (Int_t i=1; i<=n; i++)
11265 {
11266 obs=(TObjString*)fDataNames.GetObject(i,1);
11267 var=(TObjString*)fDataNames.GetObject(i,2);
11268 u=(TObjString*)fDataNames.GetObject(i,3);
11269 f=(TObjString*)fDataNames.GetObject(i,4);
11270 cout << " obsname=" << obs->GetString() << " varname=" << var->GetString() << " units=" << u->GetString() << " func=" << f->GetString() << endl;
11271 }
11272 cout << endl;
11273}
11274
11275void NcAstrolab::SetBurstParameter(TString name,Double_t value)
11276{
11401
11402 if (!fBurstParameters)
11403 {
11405 fBurstParameters->SetNameTitle("BurstParameters","Parameter settings for transient burst investigations");
11406 }
11407
11408 if (name!="*")
11409 {
11410 fBurstParameters->AddNamedSlot(name);
11411 if (name=="ESigmax" || name=="Emax") value+=1e-10; // To include the max. energy boundary in the histogram
11412 fBurstParameters->SetSignal(value,name);
11413 }
11414 else
11415 {
11416 Double_t pi=acos(-1.);
11417 name="Nmaxsrc";
11418 fBurstParameters->AddNamedSlot(name);
11419 fBurstParameters->SetSignal(-1,name);
11420 name="Nmaxevt";
11421 fBurstParameters->AddNamedSlot(name);
11422 fBurstParameters->SetSignal(-1,name);
11423 name="RAmin";
11424 fBurstParameters->AddNamedSlot(name);
11425 fBurstParameters->SetSignal(0,name);
11426 name="RAmax";
11427 fBurstParameters->AddNamedSlot(name);
11428 fBurstParameters->SetSignal(360,name);
11429 name="Declmin";
11430 fBurstParameters->AddNamedSlot(name);
11431 fBurstParameters->SetSignal(-90,name);
11432 name="Declmax";
11433 fBurstParameters->AddNamedSlot(name);
11434 fBurstParameters->SetSignal(90,name);
11435 name="T90min";
11436 fBurstParameters->AddNamedSlot(name);
11437 fBurstParameters->SetSignal(1e-5,name);
11438 name="T90max";
11439 fBurstParameters->AddNamedSlot(name);
11440 fBurstParameters->SetSignal(1e5,name);
11441 name="Zmin";
11442 fBurstParameters->AddNamedSlot(name);
11443 fBurstParameters->SetSignal(-1e-6,name);
11444 name="Zmax";
11445 fBurstParameters->AddNamedSlot(name);
11446 fBurstParameters->SetSignal(20,name);
11447 name="Sigmamin";
11448 fBurstParameters->AddNamedSlot(name);
11449 fBurstParameters->SetSignal(0,name);
11450 name="Sigmamax";
11451 fBurstParameters->AddNamedSlot(name);
11452 fBurstParameters->SetSignal(2,name);
11453 name="Grbnu";
11454 fBurstParameters->AddNamedSlot(name);
11455 fBurstParameters->SetSignal(0,name);
11456 name="Avgrbz";
11457 fBurstParameters->AddNamedSlot(name);
11458 fBurstParameters->SetSignal(-1,name);
11459 name="Avgrbt90";
11460 fBurstParameters->AddNamedSlot(name);
11461 fBurstParameters->SetSignal(-1,name);
11462 name="Inburst";
11463 fBurstParameters->AddNamedSlot(name);
11464 fBurstParameters->SetSignal(0,name);
11465 name="Dtnu";
11466 fBurstParameters->AddNamedSlot(name);
11467 fBurstParameters->SetSignal(0,name);
11468 name="Dtnus";
11469 fBurstParameters->AddNamedSlot(name);
11470 fBurstParameters->SetSignal(-0.5,name);
11471 name="ESigmin";
11472 fBurstParameters->AddNamedSlot(name);
11473 fBurstParameters->SetSignal(1e3,name);
11474 name="ESigmax";
11475 fBurstParameters->AddNamedSlot(name);
11476 fBurstParameters->SetSignal(1e10,name);
11477 name="Ezcor";
11478 fBurstParameters->AddNamedSlot(name);
11479 fBurstParameters->SetSignal(1,name);
11480 name="Emin";
11481 fBurstParameters->AddNamedSlot(name);
11482 fBurstParameters->SetSignal(200,name);
11483 name="Emax";
11484 fBurstParameters->AddNamedSlot(name);
11485 fBurstParameters->SetSignal(1e7,name);
11486 name="Alphasig";
11487 fBurstParameters->AddNamedSlot(name);
11488 fBurstParameters->SetSignal(2,name);
11489 name="Alphabkg";
11490 fBurstParameters->AddNamedSlot(name);
11491 fBurstParameters->SetSignal(3.5,name);
11492 name="Kinangle";
11493 fBurstParameters->AddNamedSlot(name);
11494 fBurstParameters->SetSignal(3,name);
11495 name="Angresmin";
11496 fBurstParameters->AddNamedSlot(name);
11497 fBurstParameters->SetSignal(0,name);
11498 name="Angresmax";
11499 fBurstParameters->AddNamedSlot(name);
11500 fBurstParameters->SetSignal(2,name);
11501 name="Angresfix";
11502 fBurstParameters->AddNamedSlot(name);
11503 fBurstParameters->SetSignal(1,name);
11504 name="Recoangle";
11505 fBurstParameters->AddNamedSlot(name);
11506 fBurstParameters->SetSignal(3,name);
11507 name="Sumsigmas";
11508 fBurstParameters->AddNamedSlot(name);
11509 fBurstParameters->SetSignal(2,name);
11510 name="Timres";
11511 fBurstParameters->AddNamedSlot(name);
11512 fBurstParameters->SetSignal(1e-5,name);
11513 name="Sensarea";
11514 fBurstParameters->AddNamedSlot(name);
11515 fBurstParameters->SetSignal(1e6,name);
11516 name="Bkgrate";
11517 fBurstParameters->AddNamedSlot(name);
11518 fBurstParameters->SetSignal(-0.003/(2.*pi),name);
11519 name="Nbkg";
11520 fBurstParameters->AddNamedSlot(name);
11521 fBurstParameters->SetSignal(1,name);
11522 name="Tunits";
11523 fBurstParameters->AddNamedSlot(name);
11524 fBurstParameters->SetSignal(2,name);
11525 name="Tmin";
11526 fBurstParameters->AddNamedSlot(name);
11527 fBurstParameters->SetSignal(-3600,name);
11528 name="Tmax";
11529 fBurstParameters->AddNamedSlot(name);
11530 fBurstParameters->SetSignal(3600,name);
11531 name="Dawin";
11532 fBurstParameters->AddNamedSlot(name);
11533 fBurstParameters->SetSignal(5,name);
11534 name="Datype";
11535 fBurstParameters->AddNamedSlot(name);
11536 fBurstParameters->SetSignal(0,name);
11537 name="Tbint90";
11538 fBurstParameters->AddNamedSlot(name);
11539 fBurstParameters->SetSignal(1,name);
11540 name="Tbin";
11541 fBurstParameters->AddNamedSlot(name);
11542 fBurstParameters->SetSignal(1,name);
11543 name="VarTbin";
11544 fBurstParameters->AddNamedSlot(name);
11545 fBurstParameters->SetSignal(10,name);
11546 name="Abin";
11547 fBurstParameters->AddNamedSlot(name);
11548 fBurstParameters->SetSignal(1,name);
11549
11550 // Remove all histograms related to burst investigations
11551 fBurstHistos.Clear();
11552 fBurstHistos.SetOwner();
11553 }
11554
11556 // Store some derived parameters //
11558
11559 // The correction factor to get from Tunits to seconds
11560 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
11561 Double_t Tfact=1;
11562 if (fTunits==0) Tfact=86400;
11563 if (fTunits==1) Tfact=3600;
11564 if (fTunits==3) Tfact=1e-9;
11565 if (fTunits==4) Tfact=1e-12;
11566 name="Tfact";
11567 fBurstParameters->AddNamedSlot(name);
11568 fBurstParameters->SetSignal(Tfact,name);
11569
11570 // Combined burst position and event reconstruction angular uncertainty interval (sigma in degrees)
11571 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
11572 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
11573 Float_t fSigmamin=fabs(fBurstParameters->GetSignal("Sigmamin"));
11574 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
11575 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
11576 if (!fRecoangle) fAngresmin=fAngresfix;
11577 Float_t Minsigmatot=-1;
11578 if (fSumsigmas==-1) Minsigmatot=fAngresmin;
11579 if (fSumsigmas==0) Minsigmatot=fSigmamin;
11580 if (fSumsigmas==1) Minsigmatot=fSigmamin+fAngresmin;
11581 if (fSumsigmas==2) Minsigmatot= sqrt(fSigmamin*fSigmamin+fAngresmin*fAngresmin);
11582 name="Minsigmatot";
11583 fBurstParameters->AddNamedSlot(name);
11584 fBurstParameters->SetSignal(Minsigmatot,name);
11585 Float_t fSigmamax=fBurstParameters->GetSignal("Sigmamax");
11586 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
11587 if (!fRecoangle) fAngresmax=fAngresfix;
11588 Float_t Maxsigmatot=-1;
11589 if (fSumsigmas==-1) Maxsigmatot=fAngresmax;
11590 if (fSumsigmas==0) Maxsigmatot=fSigmamax;
11591 if (fSumsigmas==1) Maxsigmatot=fSigmamax+fAngresmax;
11592 if (fSumsigmas==2) Maxsigmatot= sqrt(fSigmamax*fSigmamax+fAngresmax*fAngresmax);
11593 name="Maxsigmatot";
11594 fBurstParameters->AddNamedSlot(name);
11595 fBurstParameters->SetSignal(Maxsigmatot,name);
11596
11597 // The total search time window in units of "Tunits"
11598 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
11599 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
11600 Float_t Dtwin=fTmax-fTmin;
11601 name="Dtwin";
11602 fBurstParameters->AddNamedSlot(name);
11603 fBurstParameters->SetSignal(Dtwin,name);
11604
11605 Float_t fTbin=fBurstParameters->GetSignal("Tbin");
11606 if (!fTbin) // Center the time window around the burst trigger for variable time bins
11607 {
11608 fTmin=-Dtwin/2.;
11609 fTmax=Dtwin/2.;
11610 name="Tmin";
11611 fBurstParameters->AddNamedSlot(name);
11612 fBurstParameters->SetSignal(fTmin,name);
11613 name="Tmax";
11614 fBurstParameters->AddNamedSlot(name);
11615 fBurstParameters->SetSignal(fTmax,name);
11616 }
11617
11618 // The solid angle corresponding to the selected declination band
11619 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
11620 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
11621 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
11622 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
11623 Float_t phimin=fRAmin;
11624 Float_t phimax=fRAmax;
11625 Float_t thmin=90.-fDeclmax;
11626 Float_t thmax=90.-fDeclmin;
11627 Float_t OmegaDecl=GetSolidAngle(thmin,thmax,"deg",phimin,phimax,"deg");
11628 name="OmegaDecl";
11629 fBurstParameters->AddNamedSlot(name);
11630 fBurstParameters->SetSignal(OmegaDecl,name);
11631
11632 // Background event rate from the selected declination band
11633 Float_t fBkgrate=fBurstParameters->GetSignal("Bkgrate");
11634 Float_t RbkgDecl=fBkgrate;
11635 if (fBkgrate<0)
11636 {
11637 RbkgDecl=fabs(fBkgrate)*OmegaDecl;
11638 }
11639 name="RbkgDecl";
11640 fBurstParameters->AddNamedSlot(name);
11641 fBurstParameters->SetSignal(RbkgDecl,name);
11642
11643 // Mean number of background events per hour from the selected declination band
11644 Float_t NbkgHour=RbkgDecl*3600.;
11645 name="NbkgHour";
11646 fBurstParameters->AddNamedSlot(name);
11647 fBurstParameters->SetSignal(NbkgHour,name);
11648
11649 // Mean number of background events in the search time window from the selected declination band
11650 Float_t fDtwin=fBurstParameters->GetSignal("Dtwin");
11651 Float_t NbkgWin=RbkgDecl*fDtwin*Tfact;
11652 name="NbkgWin";
11653 fBurstParameters->AddNamedSlot(name);
11654 fBurstParameters->SetSignal(NbkgWin,name);
11655}
11656
11658{
11668
11669 return fBurstParameters;
11670}
11671
11673{
11683
11684 // User provided settings
11685 Int_t fNmaxsrc=TMath::Nint(fBurstParameters->GetSignal("Nmaxsrc"));
11686 Int_t fNmaxevt=TMath::Nint(fBurstParameters->GetSignal("Nmaxevt"));
11687 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
11688 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
11689 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
11690 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
11691 Float_t fT90min=fBurstParameters->GetSignal("T90min");
11692 Float_t fT90max=fBurstParameters->GetSignal("T90max");
11693 Float_t fZmin=fBurstParameters->GetSignal("Zmin");
11694 Float_t fZmax=fBurstParameters->GetSignal("Zmax");
11695 Float_t fSigmamin=fBurstParameters->GetSignal("Sigmamin");
11696 Float_t fSigmamax=fBurstParameters->GetSignal("Sigmamax");
11697 Float_t fGrbnu=fBurstParameters->GetSignal("Grbnu");
11698 Float_t fAvgrbz=fBurstParameters->GetSignal("Avgrbz");
11699 Float_t fAvgrbt90=fBurstParameters->GetSignal("Avgrbt90");
11700 Float_t fAvgrbsigma=fBurstParameters->GetSignal("Avgrbsigma");
11701 Int_t fInburst=TMath::Nint(fBurstParameters->GetSignal("Inburst"));
11702 Float_t fDtnu=fBurstParameters->GetSignal("Dtnu");
11703 Float_t fDtnus=fBurstParameters->GetSignal("Dtnus");
11704 Float_t fESigmin=fBurstParameters->GetSignal("ESigmin");
11705 Float_t fESigmax=fBurstParameters->GetSignal("ESigmax");
11706 Int_t fEzcor=TMath::Nint(fBurstParameters->GetSignal("Ezcor"));
11707 Float_t fEmin=fBurstParameters->GetSignal("Emin");
11708 Float_t fEmax=fBurstParameters->GetSignal("Emax");
11709 Int_t fKinangle=TMath::Nint(fBurstParameters->GetSignal("Kinangle"));
11710 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
11711 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
11712 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
11713 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
11714 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
11715 Float_t fTimres=fBurstParameters->GetSignal("Timres");
11716 Float_t fSensarea=fBurstParameters->GetSignal("Sensarea");
11717 Float_t fBkgrate=fBurstParameters->GetSignal("Bkgrate");
11718 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
11719 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
11720 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
11721 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
11722 Float_t fDawin=fBurstParameters->GetSignal("Dawin");
11723 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
11724 Int_t fTbint90=TMath::Nint(fBurstParameters->GetSignal("Tbint90"));
11725 Float_t fTbin=fBurstParameters->GetSignal("Tbin");
11726 Float_t fVarTbin=fBurstParameters->GetSignal("VarTbin");
11727 Float_t fAbin=fBurstParameters->GetSignal("Abin");
11728
11729 // Derived parameters
11730 Float_t fMaxsigmatot=fBurstParameters->GetSignal("Maxsigmatot");
11731 Float_t fMinsigmatot=fBurstParameters->GetSignal("Minsigmatot");
11732 Float_t fOmegaDecl=fBurstParameters->GetSignal("OmegaDecl");
11733 Float_t fRbkgDecl=fBurstParameters->GetSignal("RbkgDecl");
11734 Float_t fNbkgHour=fBurstParameters->GetSignal("NbkgHour");
11735 Float_t fNbkgWin=fBurstParameters->GetSignal("NbkgWin");
11736
11737 // Internal statistics
11738 Int_t fNgrbs=TMath::Nint(fBurstParameters->GetSignal("Ngrbs"));
11739 Int_t fNevts=TMath::Nint(fBurstParameters->GetSignal("Nevts"));
11740
11741 TString tu="days";
11742 if (fTunits==1) tu="hours";
11743 if (fTunits==2) tu="sec";
11744 if (fTunits==3) tu="ns";
11745 if (fTunits==4) tu="ps";
11746
11747 cout << " ========================= User provided source c.q. burst settings ===============================" << endl;
11748 if (fNmaxsrc<0)
11749 {
11750 printf(" No limitation has been put on the number of sources to be accepted for analysis. \n");
11751 }
11752 else
11753 {
11754 printf(" Maximal number of sources to be accepted for analysis : %-i \n",fNmaxsrc);
11755 }
11756 if (fNmaxevt<0)
11757 {
11758 printf(" No limitation has been put on the number of observed events to be accepted for analysis. \n");
11759 }
11760 else
11761 {
11762 printf(" Maximal number of observed events to be accepted for analysis : %-i \n",fNmaxevt);
11763 }
11764 printf(" Right ascension interval (J2000 in degrees) for source c.q. event position acceptance : [%-g,%-g] \n",fRAmin,fRAmax);
11765 printf(" Declination interval (J2000 in degrees) for source c.q. event position acceptance : [%-g,%-g] \n",fDeclmin,fDeclmax);
11766 printf(" Redshift interval for source acceptance : [%-g,%-g] \n",fabs(fZmin),fZmax);
11767 if (fZmin<0) printf(" Random redshift values taken from z-distribution in case of unknown redshift \n");
11768 if (fAvgrbz>=0) printf(" User defined average source redshift : %-g \n",fAvgrbz);
11769 printf(" Event energy interval (in GeV) for event acceptance : [%-g,%-g] \n",fEmin,fEmax);
11770 printf(" Position uncertainty interval (sigma in degrees) for source acceptance : [%-g,%-g] \n",fabs(fSigmamin),fSigmamax);
11771 if (fSigmamin<0) printf(" Random sigma values taken from sigma-distribution when missing in loaded data \n");
11772 printf(" Event angular resolution interval (sigma in degrees) for event acceptance : [%-g,%-g] \n",fAngresmin,fAngresmax);
11773 if (fDatype>0) printf(" Sigma (combination) selection (-1=event sigma only 0=source sigma only 1=linear summation 2=quadratic summation) : %-i \n",fSumsigmas);
11774 if (fDawin>=0)
11775 {
11776 if (fDatype<0) printf(" Unrestricted angular search area. \n");
11777 if (!fDatype) printf(" Fixed angular search circle around the source position : %-g degrees \n",fDawin);
11778 if (fDatype==1) printf(" Fixed angular search circle (in combined max. source/event sigma) around the source position : %-g \n",fDawin);
11779 if (fDatype==2) printf(" Variable angular search circle (in combined actual source/event sigma) around the source position : %-g \n",fDawin);
11780 }
11781 else
11782 {
11783 if (fDatype<0) printf(" Unrestricted angular search area. \n");
11784 if (!fDatype) printf(" Fixed angular local zenith band above/below the source position : %-g degrees \n",fabs(fDawin));
11785 if (fDatype==1) printf(" Fixed angular local zenith band (in combined max. source/event sigma) above/below the source position : %-g \n",fabs(fDawin));
11786 if (fDatype==2) printf(" Variable angular local zenith band (in combined actual source/event sigma) above/below the source position : %-g \n",fabs(fDawin));
11787 }
11788 printf(" Number of requested background patches per source : %-i \n",fNbkg);
11789 if (fT90max>0)
11790 {
11791 printf(" Duration interval (t90 in sec) for burst acceptance : [%-g,%-g] \n",fabs(fT90min),fT90max);
11792 if (fT90min<0) printf(" Random values taken from T90-distribution in case T90 and T100 were missing \n");
11793 if (fAvgrbt90>0) printf(" User defined average burst T90 duration : %-g sec. \n",fAvgrbt90);
11794 if (fTmax>fTmin) printf(" Total search time window (in %-s) with the burst trigger at t=0 : [%-g,%-g] \n",tu.Data(),fTmin,fTmax);
11795 }
11796 if (fTmax<=fTmin) printf(" Search will be performed with no restrictions on the time window \n");
11797 if (fTbin<0) printf(" Automatic time histogram binning with as mean number of bkg counts/bin : %-g \n",fabs(fTbin));
11798 if (!fTbin) printf(" Variable time histogram binning with as size (in %-s) for the first time : %-g \n",tu.Data(),fVarTbin);
11799 if (fTbin>0)
11800 {
11801 if (fTbint90)
11802 {
11803 printf(" Time histogram bin size in average T90 units : %-g",fTbin);
11804 if (fAvgrbt90>0 || fNgrbs>0) printf(" (=%-g sec)",fTbin*fabs(fAvgrbt90));
11805 printf("\n");
11806 }
11807 else
11808 {
11809 printf( " Time histogram bin size : %-g %-s \n",fTbin,tu.Data());
11810 }
11811 }
11812 if (fAbin<0)
11813 {
11814 printf(" Automatic angular histogram binning with as mean number of bkg counts per bin : %-g \n",fabs(fAbin));
11815 }
11816 else
11817 {
11818 printf(" Angular histogram bin size : %-g degrees \n",fAbin);
11819 }
11820
11821 // Parameters for burst signal and background generation
11822 if (fGrbnu)
11823 {
11824 if (fGrbnu<0)
11825 {
11826 printf(" Number of generated neutrinos per burst : %-g without statistical fluctuations \n",fabs(fGrbnu));
11827 }
11828 else
11829 {
11830 printf(" Maximum number of generated neutrinos per burst : %-g \n",fGrbnu);
11831 printf(" The actual number of neutrinos may be less due to statistical fluctuations \n");
11832 }
11833 if (!fInburst)
11834 {
11835 printf(" Neutrino production is assumed to be NOT coupled to the observed burst duration \n");
11836 printf(" Mean decoupled time difference between burst gammas/GW and neutrinos : %-g sec. \n",fDtnu);
11837 }
11838 else
11839 {
11840 printf(" Neutrino production is assumed to be coupled to the observed burst duration \n");
11841 printf(" Mean coupled time difference (in units of T90 w.r.t. trigger) between burst gammas/GW and neutrinos : %-g",fDtnu);
11842 }
11843 if (fDtnus>=0)
11844 {
11845 printf(" Sigma of mean time difference between burst gammas/GW flash and neutrinos : %-g sec. \n",fDtnus);
11846 }
11847 else
11848 {
11849 printf(" Sigma of mean time difference (in units of T90) between burst gammas/GW flash and neutrinos : %-g \n",fabs(fDtnus));
11850 }
11851 TString str;
11852 if (fSigEmode=="SigE")
11853 {
11854 str="Signal energy PDF at the source : dN/dE=";
11855 }
11856 else
11857 {
11858 str="Signal energy profile at Earth : dN/dE";
11859 }
11860 str+=fSigEprofile.GetExpFormula("p");
11861 str.ReplaceAll("x","E");
11862 if (fSigEmode=="SigS") str+=" cm^-2";
11863 if (fSigEmode=="SigF") str+=" cm^-2 s^-1";
11864 if (fSigEmode=="SigI") str+=" cm^-2 s^-1 sr^-1";
11865 printf(" %-s within [%-g,%-g] GeV \n",str.Data(),fESigmin,fESigmax);
11866 if (fSigEmode=="SigE")
11867 {
11868 if (fEzcor)
11869 {
11870 printf(" The signal neutrino energy at Earth will be corrected for redshift \n");
11871 }
11872 else
11873 {
11874 printf(" No redshift correction will be applied on the generated signal neutrino energy \n");
11875 }
11876 }
11877 if (fBkgEmode=="BkgE")
11878 {
11879 str="Background energy PDF at Earth : dN/dE=";
11880 }
11881 else
11882 {
11883 str="Background energy profile at Earth : dN/dE=";
11884 }
11885 str+=fBkgEprofile.GetExpFormula("p");
11886 str.ReplaceAll("x","E");
11887 if (fBkgEmode=="BkgS") str+=" cm^-2";
11888 if (fBkgEmode=="BkgF") str+=" cm^-2 s^-1";
11889 if (fBkgEmode=="BkgI") str+=" cm^-2 s^-1 sr^-1";
11890 printf(" %-s within [%-g,%-g] GeV \n",str.Data(),fEmin,fEmax);
11891 printf(" Fixed event reco angular resolution (sigma in degrees), also used when no distribution (value) is available : %-g \n",fAngresfix);
11892 printf(" Event reconstruction angular uncertainty selection (0=use fixed value 1=mean 2=median 3=draw from distribution) : %-i \n",fRecoangle);
11893 printf(" Neutrino-lepton kinematic opening angle selection for CC interactions (0=none 1=mean 2=median 3=draw from pdf) : %-i \n",fKinangle);
11894 }
11895
11896 printf("\n");
11897 printf(" Time resolution of the neutrino detector : %-g sec. \n",fTimres);
11898 printf(" Area covered c.q. overlooked by the neutrino detector : %-g m^2 \n",fSensarea);
11899 if (fBkgrate) printf(" User defined mean rate of background events for the specified declination interval (<0 : rate per steradian) : %-g Hz \n",fBkgrate);
11900
11901 printf("\n");
11902 printf(" ============================== Derived parameters ==================================== \n");
11903 printf(" Combined source position and event reco angular uncertainty interval (sigma in degrees) : [%-g,%-g] \n",fMinsigmatot,fMaxsigmatot);
11904 printf(" Solid angle coverage corresponding to the selected declination band : %-g steradian \n",fOmegaDecl);
11905 if (fBkgrate)
11906 {
11907 printf(" Background event rate (from user setting) for the selected declination band : %-g Hz \n",fRbkgDecl);
11908 printf(" Mean number of background events (from user setting) per hour from the selected declination band : %-g \n",fNbkgHour);
11909 printf(" Mean number of background events (from user setting) in the time window from the selected declination band : %-g \n",fNbkgWin);
11910 }
11911 if (fNgrbs>0)
11912 {
11913 printf(" Number of bursts accepted for analysis : %-i \n",fNgrbs);
11914 printf(" Median source redshift from the data sample : %-g \n",fabs(fAvgrbz));
11915 if (fAvgrbt90) printf(" Median burst T90 duration from the data sample : %-g sec. \n",fabs(fAvgrbt90));
11916 printf(" Median souce position uncertainty (sigma in degrees) from the data sample : %-g \n",fAvgrbsigma);
11917 }
11918 if (fNevts>0) printf(" Number of observed events accepted for analysis : %-i \n",fNevts);
11919 printf(" ====================================================================================== \n");
11920 printf("\n");
11921}
11922
11923void NcAstrolab::LoadInputData(Bool_t src,TString file,TString tree,Int_t date1,Int_t date2,Int_t nmax,TString type)
11924{
11981
11982 // Set the default type identifier
11983 if (type=="-" && src) type="GRB";
11984 if (type=="-" && !src) type="EVT";
11985
11986 Int_t nvars=fDataNames.GetMaxRow();
11987
11988 if (nvars<1)
11989 {
11990 cout << " *" << ClassName() << "::LoadInputData* No variables were specified for " << type << " data."<< endl;
11991 return;
11992 }
11993
11994 // Set the data mode : observed events or source data
11995 Int_t iobs=1;
11996 if (src) iobs=0;
11997
11998 // Retreive the needed parameters
11999 Int_t fNmaxsrc=TMath::Nint(fBurstParameters->GetSignal("Nmaxsrc"));
12000 Int_t fNmaxevt=TMath::Nint(fBurstParameters->GetSignal("Nmaxevt"));
12001 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
12002 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
12003 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
12004 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
12005 Float_t fT90min=fBurstParameters->GetSignal("T90min");
12006 Float_t fT90max=fBurstParameters->GetSignal("T90max");
12007 Float_t fZmin=fBurstParameters->GetSignal("Zmin");
12008 Float_t fZmax=fBurstParameters->GetSignal("Zmax");
12009 Float_t fSigmamin=fBurstParameters->GetSignal("Sigmamin");
12010 Float_t fSigmamax=fBurstParameters->GetSignal("Sigmamax");
12011 Float_t fEmin=fBurstParameters->GetSignal("Emin");
12012 Float_t fEmax=fBurstParameters->GetSignal("Emax");
12013 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
12014 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
12015
12016 // Internal statistics
12017 Int_t fNgrbs=GetNsignals(0);
12018 Int_t fNevts=GetNsignals(1);
12019
12020 // Get access to a redshift distribution to draw randomly source redshifts if needed
12021 TH1* zdist=0;
12022 if (src && fZmin<0) zdist=GetBurstZdist("LoadInputData()",type);
12023
12024 // Get access to a T90 distribution to draw randomly source c.q. burst T90 values if needed
12025 TH1* t90dist=0;
12026 if (src && fT90min<0) t90dist=GetBurstT90dist("LoadInputData()",type);
12027
12028 // Get access to a 1-sigma position uncertainty distribution to draw randomly source position uncertaintes
12029 TH1* sigmaposdist=0;
12030 if (src && fSigmamin<0) sigmaposdist=GetBurstSigmaPosdist("LoadInputData()",type);
12031
12032 // The TTree containing the source (c.q. burst) or observed event data
12033 TChain data(tree.Data());
12034 data.Add(file.Data());
12035
12036 // The pre-defined (physical) observables
12037 TString obsname;
12038 TString varname;
12039 TString units;
12040 TString func;
12041
12042 // The (physical) observable value in string format
12043 TObjString* pval=0;
12044 TString val;
12045
12046 // The retrieved numerical (physical) observable value from the ROOT Tree
12047 Double_t value=0;
12048
12049 // The conversion factor depending on the units specification
12050 Double_t fact=0;
12051
12052 // Some of the pre-defined observable values that are used for selections
12053 // or that need special treatment
12054 TString Name,Date,Tobs,Tstart,Tend;
12055 Double_t d,a,b;
12056 Float_t z,csigma,T90,T100,E;
12057
12058 UInt_t yyyy,mm,dd; // The date format
12059 Int_t h,m; // The integer hour and minute time format
12060 Double_t s; // The (fractional) seconds time format
12061 Int_t dmode=0;
12062 Int_t idate=0;
12063 Int_t jdate=0;
12064 TString grbname;
12065 NcTimestamp tobs;
12066 NcTimestamp tstart;
12067 NcTimestamp tend;
12068 NcSignal* sx=0;
12069 Int_t nnew=0;
12070 TLeaf* lx=0;
12071 TLeafC* lxc=0;
12072 Int_t jlast=0;
12073
12074 // Create or increase the corresponding storage array to hold the new data
12075 Int_t nent=data.GetEntries();
12076 Int_t size=0;
12077 if (src) // Input represents reference objects
12078 {
12079 if (!fRefs)
12080 {
12081 fRefs=new TObjArray(nent);
12082 fRefs->SetOwner();
12083 }
12084 else
12085 {
12086 size=fRefs->GetSize();
12087 fRefs->Expand(size+nent);
12088 }
12089 }
12090 else // Input represents measured signals
12091 {
12092 if (!fSigs)
12093 {
12094 fSigs=new TObjArray(nent);
12095 fSigs->SetOwner();
12096 }
12097 else
12098 {
12099 size=fSigs->GetSize();
12100 fSigs->Expand(size+nent);
12101 }
12102 }
12103
12104 // Loop over the data entries in the input Tree
12105 for (Int_t ient=0; ient<nent; ient++)
12106 {
12107 if (nmax>=0 && nnew>=nmax) break;
12108 if (src && fNmaxsrc>=0 && (fNgrbs+nnew)>=fNmaxsrc) break;
12109 if (!src && fNmaxevt>=0 && (fNevts+nnew)>=fNmaxevt) break;
12110
12111 data.GetEntry(ient);
12112
12113 // Initialisation of the values that are used for selections
12114 // or that need special treatment
12115 Name="none";
12116 Date="none";
12117 Tobs="none";
12118 Tstart="none";
12119 Tend="none";
12120 d=-999;
12121 a=-999;
12122 b=-999;
12123 z=-999;
12124 csigma=-999;
12125 T90=-999;
12126 T100=-999;
12127 E=-999;
12128
12129 // Loop over the selected input variables and retrieve the corresponding input value
12130 for (Int_t ivar=1; ivar<=nvars; ivar++)
12131 {
12132 obsname=((TObjString*)fDataNames.GetObject(ivar,1))->GetString();
12133 varname=((TObjString*)fDataNames.GetObject(ivar,2))->GetString();
12134 units=((TObjString*)fDataNames.GetObject(ivar,3))->GetString();
12135 func=((TObjString*)fDataNames.GetObject(ivar,4))->GetString();
12136
12137 pval=(TObjString*)fDataNames.GetObject(ivar,5);
12138
12139 if (!pval) continue;
12140
12141 lx=data.GetLeaf(varname);
12142
12143 // Record -999 for missing data
12144 if (!lx)
12145 {
12146 pval->SetString("-999");
12147 continue;
12148 }
12149
12150 if (obsname=="Name") // Character string data from the input Tree
12151 {
12152 value=0;
12153 lxc=(TLeafC*)lx;
12154 Name=lxc->GetValueString();
12155 }
12156 else // Numerical data from the input Tree
12157 {
12158 value=lx->GetValue();
12159 }
12160
12161 if (func=="Log") value=pow(10,value);
12162 if (func=="Ln") value=exp(value);
12163
12164 // Convert all angular values to degrees
12165 if (obsname=="a" || obsname=="b" || obsname=="csigma") value=ConvertAngle(value,units,"deg");
12166
12167 // Convert numerical values to the standard units
12168 if (units.IsFloat())
12169 {
12170 fact=units.Atof();
12171 value*=fact;
12172 }
12173
12174 // Store the obtained value in string format
12175 val="";
12176 val+=value;
12177 pval->SetString(val);
12178
12179 // Special values needed for later selections
12180 if (obsname=="Date")
12181 {
12182 Date="";
12183 Date+=int(value);
12184 if (units=="ddmmyyyy") dmode=0;
12185 if (units=="yyyymmdd") dmode=1;
12186 if (units=="mmddyyyy") dmode=2;
12187 if (units=="yyyyddmm") dmode=3;
12188 }
12189 if (obsname=="Tobs")
12190 {
12191 Tobs="set"; // Indicate that Tobs is encountered
12192 if (units=="JD") tobs.SetJD(value);
12193 if (units=="MJD") tobs.SetMJD(value);
12194 if (units=="TJD") tobs.SetTJD(value);
12195 if (units=="hms")
12196 {
12197 Tobs="";
12198 Tobs+=value;
12199 }
12200 if (units=="hrs") // Convert "hrs" to "hms" time format
12201 {
12202 Tobs="";
12203 Convert(value,h,m,s);
12204 value=s+double(100*m+10000*h);
12205 Tobs+=value;
12206 }
12207 }
12208 if (obsname=="Tstart")
12209 {
12210 Tstart="set"; // Indicate that Tstart is encountered
12211 if (units=="JD") tstart.SetJD(value);
12212 if (units=="MJD") tstart.SetMJD(value);
12213 if (units=="TJD") tstart.SetTJD(value);
12214 if (units=="hms")
12215 {
12216 Tstart="";
12217 Tstart+=value;
12218 }
12219 if (units=="hrs") // Convert "hrs" to "hms" time format
12220 {
12221 Tstart="";
12222 Convert(value,h,m,s);
12223 value=s+double(100*m+10000*h);
12224 Tstart+=value;
12225 }
12226 }
12227 if (obsname=="Tend")
12228 {
12229 Tend="set"; // Indicate that Tend is encountered
12230 if (units=="JD") tend.SetJD(value);
12231 if (units=="MJD") tend.SetMJD(value);
12232 if (units=="TJD") tend.SetTJD(value);
12233 if (units=="hms")
12234 {
12235 Tend="";
12236 Tend+=value;
12237 }
12238 if (units=="hrs") // Convert "hrs" to "hms" time format
12239 {
12240 Tend="";
12241 Convert(value,h,m,s);
12242 value=s+double(100*m+10000*h);
12243 Tend+=value;
12244 }
12245 }
12246
12247 if (obsname=="d") d=value;
12248 if (obsname=="a") a=value;
12249 if (obsname=="b") b=value;
12250 if (obsname=="z") z=value;
12251 if (obsname=="csigma") csigma=value;
12252 if (obsname=="T90") T90=value;
12253 if (obsname=="T100") T100=value;
12254 if (obsname=="E") E=value;
12255 } // End of the loop over the selected input variables
12256
12257 // For angular coordinates the distance may be irrelevant
12258 if (d<=0) d=1;
12259
12260 // Check for the presence of valid location data
12261 if (a<-900 || b<-900) continue;
12262
12263 // Check on (RA,DEC) acceptance in case of J2000 equatorial coordinates
12264 if (fDataFrame=="equ" && fDataMode=="J" && (a<fRAmin || a>fRAmax || b<fDeclmin || b>fDeclmax)) continue;
12265
12266 // Construct the various timestamps from the (date,time) specification if needed
12267 if (Tobs!="none" && Tobs!="set" && Date!="none") tobs.SetUT(Date,Tobs,dmode);
12268 if (Tstart!="none" && Tstart!="set" && Date!="none") tstart.SetUT(Date,Tstart,dmode);
12269 if (Tend!="none" && Tend!="set" && Date!="none") tend.SetUT(Date,Tend,dmode);
12270
12271 // Check for the presence of a valid observation c.q. trigger timestamp
12272 if (Tobs=="none" || (Tobs!="set" && Date=="none")) continue;
12273
12274 // Obtain the date in yyyymmdd format
12275 tobs.GetDate(kTRUE,0,&yyyy,&mm,&dd);
12276 idate=dd+100*mm+10000*yyyy;
12277
12278 if (Name!="none") // Set the name of the object or observation
12279 {
12280 grbname=Name;
12281 }
12282 else // Compose the name of the source c.q. burst with the common yymmdd suffix
12283 {
12284 jdate=idate%1000000;
12285 grbname=type;
12286 if (jdate<100000) grbname+="0"; // Add leading zero for the year if needed
12287 grbname+=jdate;
12288 }
12289
12290 if (date1 && idate<date1) continue;
12291 if (date2 && idate>date2) continue;
12292
12293 if (src) // Source c.q. burst specific selections
12294 {
12295 if (T90<=0) T90=T100;
12296 if (fT90min<0 && T90<0 && t90dist) T90=t90dist->GetRandom();
12297
12298 if (T90<fabs(fT90min) || T90>fT90max) continue;
12299
12300 if (fZmin<0 && z<0 && zdist) z=zdist->GetRandom();
12301
12302 if (z<fabs(fZmin) || z>fZmax) continue;
12303
12304 if (fSigmamin<0 && csigma<0 && sigmaposdist) csigma=sigmaposdist->GetRandom();
12305
12306 if (csigma<fabs(fSigmamin) || csigma>fSigmamax) continue;
12307 }
12308 else // Observed event specific selections
12309 {
12310 if (E<fEmin || E>fEmax) continue;
12311 if (csigma<fAngresmin || csigma>fAngresmax) continue;
12312 }
12313
12314 // Store the location c.q. arrival direction data
12315 sx=SetSignal(d,a,"deg",b,"deg",fDataFrame,&tobs,-1,fDataMode,grbname,iobs);
12316
12317 // Obtain the RA and DEC coordinates for acceptance selection if input was not in J2000
12318 if (fDataFrame!="equ" || fDataMode!="J")
12319 {
12320 jlast=GetSignalIndex(sx,iobs);
12321 GetSignal(d,a,"deg",b,"deg","equ",&tobs,jlast,"J",iobs);
12322
12323 // Remove the signal again when it falls outside the acceptance
12324 if (a<fRAmin || a>fRAmax || b<fDeclmin || b>fDeclmax)
12325 {
12326 RemoveSignal(jlast,iobs,0);
12327 sx=0;
12328 continue;
12329 }
12330 }
12331
12332 if (!sx) continue;
12333
12334 nnew++;
12335
12336 // Storing the requested data in NcSignal slots
12337 for (Int_t ivar=1; ivar<=nvars; ivar++)
12338 {
12339 obsname=((TObjString*)fDataNames.GetObject(ivar,1))->GetString();
12340 val=((TObjString*)fDataNames.GetObject(ivar,5))->GetString();
12341
12342 // The observable Name is not stored in the NcSignal slots
12343 if (obsname=="Name") continue;
12344
12345 value=val.Atof();
12346
12347 // The values of the observables a and b depend on the reference frame
12348 // They should be retrieved via the GetSignal() facility
12349 if (obsname=="a" || obsname=="b") continue;
12350
12351 // The Date and timestamps in specific format
12352 if (obsname=="Date") value=idate;
12353 if (obsname=="Tobs") value=tobs.GetMJD();
12354 if (obsname=="Tstart") value=tstart.GetMJD();
12355 if (obsname=="TEnd") value=tend.GetMJD();
12356
12357 // Values that may have got random values
12358 if (obsname=="z") value=z;
12359 if (obsname=="csigma") value=csigma;
12360 if (obsname=="T90") value=T90;
12361
12362 sx->AddNamedSlot(obsname);
12363 sx->SetSignal(value,obsname);
12364 }
12365
12366 if (!src) continue;
12367
12368 // Determine the average number of observable signal events for this burst
12370 } // End of loop over the entries of the input Tree
12371
12372 // Compress the storage array size to the number of actually stored elements
12373 RemoveSignal(-1,iobs,1);
12374
12375 Int_t nstored=GetNsignals(iobs);
12376
12377 cout << endl;
12378 if (src)
12379 {
12380 // Update internal statistics
12381 fBurstParameters->AddNamedSlot("Ngrbs");
12382 fBurstParameters->SetSignal(nstored,"Ngrbs");
12383 cout << " *" << ClassName() << "::LoadInputData* " << nnew << " new source(s) of type " << type
12384 << " stored from Tree:" << tree << " of file(s):" << file << endl;
12385 cout << " Total number of stored sources c.q. bursts : " << nstored << endl;
12386 }
12387 else
12388 {
12389 // Update internal statistics
12390 fBurstParameters->AddNamedSlot("Nevts");
12391 fBurstParameters->SetSignal(nstored,"Nevts");
12392 cout << " *" << ClassName() << "::LoadInputData* " << nnew
12393 << " new observed event(s) were stored from Tree:" << tree << " of file(s):" << file << endl;
12394 cout << " Total number of stored events : " << nstored << endl;
12395 }
12396}
12397
12398void NcAstrolab::LoadAeffData(TString file,TString hist)
12399{
12421
12422 // Expand the input file pathname
12423 file=gSystem->ExpandPathName(file.Data());
12424
12425 TFile f(file.Data());
12426 TH2* h=(TH2*)f.Get(hist.Data());
12427
12428 if (!h)
12429 {
12430 printf("*%-s::LoadAeffData* No 2D histogram with Aeff data found with name : %-s \n",ClassName(),hist.Data());
12431 return;
12432 }
12433
12434 TH2* hAeffProfile=(TH2*)h->Clone("hAeffProfile");
12435 hAeffProfile->SetDirectory(0); // Disonnect this histogram from the TFile f
12436
12437 fBurstHistos.Add(hAeffProfile);
12438
12439 printf("\n *%-s::LoadAeffData* 2D histogram hAeffProfile(log(E),cos(theta)) with effective area data stored. \n",ClassName());
12440 printf(" The data were obtained from the file : %-s \n",file.Data());
12441
12442 // Create a signal and/or background NuCount and Zenith profile by using the corresponding energy profile(s), if any.
12444}
12445
12447{
12465
12466 Double_t fESigmin=fBurstParameters->GetSignal("ESigmin");
12467 Double_t fESigmax=fBurstParameters->GetSignal("ESigmax");
12468 Double_t fEmin=fBurstParameters->GetSignal("Emin");
12469 Double_t fEmax=fBurstParameters->GetSignal("Emax");
12470
12471 TH2* hAeffProfile=(TH2*)fBurstHistos.FindObject("hAeffProfile");
12472 TH1* hSigEprofile=(TH1*)fBurstHistos.FindObject("hSigEprofile");
12473 TH1* hBkgEprofile=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
12474
12475 if (!hAeffProfile) return;
12476
12477 TAxis* xaxis=hAeffProfile->GetXaxis();
12478 TAxis* yaxis=hAeffProfile->GetYaxis();
12479
12480 if (!xaxis || !yaxis) return;
12481
12482 Int_t nebins=xaxis->GetNbins();
12483 Double_t emin=xaxis->GetXmin();
12484 Double_t emax=xaxis->GetXmax();
12485
12486 Int_t nabins=yaxis->GetNbins();
12487 Double_t amin=yaxis->GetXmin();
12488 Double_t amax=yaxis->GetXmax();
12489
12490 TH2* hSigNuCountProfile=(TH2*)fBurstHistos.FindObject("hSigNuCountProfile");
12491 TH2* hBkgNuCountProfile=(TH2*)fBurstHistos.FindObject("hBkgNuCountProfile");
12492 TH1* hSigZenithProfile=(TH1F*)fBurstHistos.FindObject("hSigZenithProfile");
12493 TH1* hBkgZenithProfile=(TH1F*)fBurstHistos.FindObject("hBkgZenithProfile");
12494
12495 Double_t aeff=0;
12496 Double_t integral=0;
12497 Double_t count=0;
12498 Double_t xlow=0;
12499 Double_t xup=0;
12500 TString title="";
12501
12502 // Create the distributions for signal data
12503 if (hSigEprofile && (mode=="Aeff" || mode=="SigS" || mode=="SigF" || mode=="SigI"))
12504 {
12505 title="Contraction of hSigEprofile and hAeffProfile;Log(E) in GeV;Cosine of the Zenith angle (#theta);Counts";
12506 if (mode.Contains("F")) title+=" s^{-1}";
12507 if (mode.Contains("I")) title+=" s^{-1} sr^{ -1}";
12508 if (!hSigNuCountProfile)
12509 {
12510 hSigNuCountProfile=(TH2*)hAeffProfile->Clone("hSigNuCountProfile");
12511 hSigNuCountProfile->Reset();
12512 hSigNuCountProfile->SetTitle(title);
12513 fBurstHistos.Add(hSigNuCountProfile);
12514 }
12515 else if (mode.Contains("Sig")) // Only renew in case of a new Signal energy profile
12516 {
12517 hSigNuCountProfile->Reset();
12518 hSigNuCountProfile->SetBins(nebins,emin,emax,nabins,amin,amax);
12519 hSigNuCountProfile->SetTitle(title);
12520 }
12521
12522 for (Int_t abin=1; abin<=nabins; abin++) // Loop over the cos(theta) bins
12523 {
12524 for (Int_t ebin=1; ebin<=nebins; ebin++) // Loop over the energy bins of hAeffProfile for this theta bin
12525 {
12526 xlow=xaxis->GetBinLowEdge(ebin);
12527 xup=xaxis->GetBinUpEdge(ebin);
12528 xlow=pow(10,xlow);
12529 xup=pow(10,xup);
12530 if (xup<fESigmin || xlow>fESigmax) continue;
12531 if (xlow<fESigmin && xup>fESigmin) xlow=fESigmin;
12532 if (xup>fESigmax && xlow<fESigmax) xup=fESigmax;
12533 aeff=hAeffProfile->GetBinContent(ebin,abin);
12534 integral=fSigEprofile.Integral(xlow,xup);
12535 count=aeff*integral;
12536 hSigNuCountProfile->SetBinContent(ebin,abin,count);
12537 }
12538 }
12539
12540 // Create also the Zenith profile
12541 title="Projection of hSigNuCountProfile;Cosine of the Zenith angle (#theta);Counts";
12542 if (mode.Contains("F")) title+=" s^{-1}";
12543 if (mode.Contains("I")) title+=" s^{-1} sr^{ -1}";
12544
12545 if (!hSigZenithProfile)
12546 {
12547 hSigZenithProfile=hSigNuCountProfile->ProjectionY("hSigZenithProfile");
12548 fBurstHistos.Add(hSigZenithProfile);
12549 }
12550 else if (mode.Contains("Sig")) // Only renew in case of a new Signal energy profile
12551 {
12552 delete hSigZenithProfile;
12553 hSigZenithProfile=hSigNuCountProfile->ProjectionY("hSigZenithProfile");
12554 }
12555 hSigZenithProfile->SetTitle(title);
12556 }
12557
12558 // Create the distributions for background data
12559 if (hBkgEprofile && (mode=="Aeff" || mode=="BkgS" || mode=="BkgF" || mode=="BkgI"))
12560 {
12561 title="Contraction of hBkgEprofile and hAeffProfile;Log(E) in GeV;Cosine of the Zenith angle (#theta);Counts";
12562 if (mode.Contains("F")) title+=" s^{-1}";
12563 if (mode.Contains("I")) title+=" s^{-1} sr^{ -1}";
12564
12565 if (!hBkgNuCountProfile)
12566 {
12567 hBkgNuCountProfile=(TH2*)hAeffProfile->Clone("hBkgNuCountProfile");
12568 hBkgNuCountProfile->Reset();
12569 hBkgNuCountProfile->SetTitle(title);
12570 fBurstHistos.Add(hBkgNuCountProfile);
12571 }
12572 else if (mode.Contains("Bkg")) // Only renew in case of a new Background energy profile
12573 {
12574 hBkgNuCountProfile->Reset();
12575 hBkgNuCountProfile->SetBins(nebins,emin,emax,nabins,amin,amax);
12576 hBkgNuCountProfile->SetTitle(title);
12577 }
12578
12579 for (Int_t abin=1; abin<=nabins; abin++) // Loop over the cos(theta) bins
12580 {
12581 for (Int_t ebin=1; ebin<=nebins; ebin++) // Loop over the energy bins of hAeffProfile for this theta bin
12582 {
12583 xlow=xaxis->GetBinLowEdge(ebin);
12584 xup=xaxis->GetBinUpEdge(ebin);
12585 xlow=pow(10,xlow);
12586 xup=pow(10,xup);
12587 if (xup<fEmin || xlow>fEmax) continue;
12588 if (xlow<fEmin && xup>fEmin) xlow=fEmin;
12589 if (xup>fEmax && xlow<fEmax) xup=fEmax;
12590 aeff=hAeffProfile->GetBinContent(ebin,abin);
12591 integral=fBkgEprofile.Integral(xlow,xup);
12592 count=aeff*integral;
12593 hBkgNuCountProfile->SetBinContent(ebin,abin,count);
12594 }
12595 }
12596
12597 // Create also the Zenith profile
12598 title="Projection of hBkgNuCountProfile;Cosine of the Zenith angle (#theta);Counts";
12599 if (mode.Contains("F")) title+=" s^{-1}";
12600 if (mode.Contains("I")) title+=" s^{-1} sr^{ -1}";
12601
12602 if (!hBkgZenithProfile)
12603 {
12604 hBkgZenithProfile=hBkgNuCountProfile->ProjectionY("hBkgZenithProfile");
12605 fBurstHistos.Add(hBkgZenithProfile);
12606 }
12607 else if (mode.Contains("Bkg")) // Only renew in case of a new Signal energy profile
12608 {
12609 delete hBkgZenithProfile;
12610 hBkgZenithProfile=hBkgNuCountProfile->ProjectionY("hBkgZenithProfile");
12611 }
12612 hBkgZenithProfile->SetTitle(title);
12613 }
12614}
12615
12616void NcAstrolab::GenBurstGCNdata(Int_t n,TString name,Bool_t scale)
12617{
12638
12639 // Retreive the needed parameters
12640 Int_t fNmaxsrc=TMath::Nint(fBurstParameters->GetSignal("Nmaxsrc"));
12641 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
12642 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
12643 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
12644 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
12645 Float_t fT90min=fBurstParameters->GetSignal("T90min");
12646 Float_t fT90max=fBurstParameters->GetSignal("T90max");
12647 Float_t fZmin=fBurstParameters->GetSignal("Zmin");
12648 Float_t fZmax=fBurstParameters->GetSignal("Zmax");
12649 Float_t fSigmamin=fBurstParameters->GetSignal("Sigmamin");
12650 Float_t fSigmamax=fBurstParameters->GetSignal("Sigmamax");
12651 Float_t fOmegaDecl=fBurstParameters->GetSignal("OmegaDecl");
12652
12653 if (scale)
12654 {
12655 Double_t pi=acos(-1.);
12656 n=TMath::Nint(double(n)*fOmegaDecl/(4.*pi));
12657 }
12658
12659 // Internal statistics
12660 Int_t fNgrbs=GetNsignals(0);
12661
12662 // Get access to a redshift distribution to draw randomly redshifts
12663 TH1* zdist=GetBurstZdist("GenBurstGCNdata()",name);
12664
12665 // Get access to a T90 distribution to draw randomly T90 values
12666 TH1* t90dist=GetBurstT90dist("GenBurstGCNdata()",name);
12667
12668 // Get access to a 1-sigma position uncertainty distribution to draw randomly position uncertaintes
12669 TH1* sigmaposdist=GetBurstSigmaPosdist("GenBurstGCNdata()",name);
12670
12671 if (!zdist || !t90dist || !sigmaposdist)
12672 {
12673 cout << endl;
12674 cout << " *" << ClassName() << "::GenBurstGCNdata* A distribution for random values is missing." << endl;
12675 cout << endl;
12676 return;
12677 }
12678
12679 Float_t thlow=90.-fDeclmax; // Lower theta angle in overall Earth spherical coordinates (North Pole is theta=0)
12680 Float_t thup=90.-fDeclmin; // Upper theta angle in overall Earth spherical coordinates (North Pole is theta=0)
12681 Float_t phimin=fRAmin; // Minimal phi angle in overall Earth spherical coordinates
12682 Float_t phimax=fRAmax; // Maximal phi angle in overall Earth spherical coordinates
12683 if (thlow<0) thlow=0;
12684 if (thup>180) thup=180;
12685
12686 NcSignal* sx=0;
12687 NcPosition rgrb;
12688 Float_t t90grb=0;
12689 Float_t zgrb=0;
12690 Float_t sigmagrb=0;
12691 TString grbname;
12692 Double_t thetagrb,phigrb,ragrb,decgrb;
12693 Int_t ngen=0;
12694
12695 for (Int_t igrb=1; igrb<=n; igrb++)
12696 {
12697 if (fNmaxsrc>=0 && (fNgrbs+ngen)>=fNmaxsrc) break;
12698
12699 zgrb=-1;
12700 if (fabs(fZmin)==fZmax) zgrb=fZmax;
12701 while (zgrb<fabs(fZmin) || zgrb>fZmax)
12702 {
12703 zgrb=zdist->GetRandom();
12704 }
12705
12706 t90grb=-1;
12707 if (fabs(fT90min)==fT90max) t90grb=fT90max;
12708 while (t90grb<fabs(fT90min) || t90grb>fT90max)
12709 {
12710 t90grb=t90dist->GetRandom();
12711 t90grb=pow(float(10),t90grb);
12712 }
12713
12714 sigmagrb=-1;
12715 if (fabs(fSigmamin)==fSigmamax) sigmagrb=fSigmamax;
12716 while (sigmagrb<fabs(fSigmamin) || sigmagrb>fSigmamax)
12717 {
12718 sigmagrb=sigmaposdist->GetRandom();
12719 }
12720
12721 rgrb.SetPosition(1,0,0,"sph","deg");
12722 RandomPosition(rgrb,thlow,thup,phimin,phimax);
12723 thetagrb=rgrb.GetX(2,"sph","deg");
12724 phigrb=rgrb.GetX(3,"sph","deg");
12725
12726 grbname="Random-";
12727 grbname+=name;
12728 grbname+=igrb;
12729 grbname+="#";
12730 ragrb=phigrb;
12731 decgrb=90.-thetagrb;
12732 sx=SetSignal(1,ragrb,"deg",decgrb,"deg","equ",0,-1,"J",grbname);
12733
12734 if (!sx) continue;
12735
12736 ngen++;
12737
12738 sx->AddNamedSlot("T90");
12739 sx->SetSignal(t90grb,"T90");
12740 sx->AddNamedSlot("csigma");
12741 sx->SetSignal(sigmagrb,"csigma");
12742 sx->AddNamedSlot("z");
12743 sx->SetSignal(zgrb,"z");
12744
12745 // Determine the average number of observable signal events for this burst
12747 }
12748
12749 // Update internal statistics
12750 fNgrbs=GetNsignals(0);
12751 fBurstParameters->AddNamedSlot("Ngrbs");
12752 fBurstParameters->SetSignal(fNgrbs,"Ngrbs");
12753
12754 printf("\n *%-s::GenBurstGCNdata* %-i new generated bursts with name %-s were stored. \n",ClassName(),ngen,name.Data());
12755 printf(" Total number of stored bursts : %-i \n",fNgrbs);
12756}
12757
12759{
12767
12768 if (!sx) return;
12769
12770 TH2* hSigNuCountProfile=(TH2*)fBurstHistos.FindObject("hSigNuCountProfile");
12771 TH2* hBkgNuCountProfile=(TH2*)fBurstHistos.FindObject("hSigNuCountProfile");
12772
12773 Float_t fOmegaDecl=fBurstParameters->GetSignal("OmegaDecl");
12774 Float_t fDtwin=fBurstParameters->GetSignal("Dtwin");
12775 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
12776
12777 NcTimestamp* ts=sx->GetTimestamp();
12778 Int_t index=GetSignalIndex(sx,0);
12779 Double_t rgrb=0;
12780 Double_t thetagrb=0;
12781 Double_t phigrb=0;
12782 GetSignal(rgrb,thetagrb,"rad",phigrb,"rad","loc",ts,index,"T",0);
12783
12784 TAxis* axis=0;
12785 Int_t nbins=0;
12786 Int_t jbin=0;
12787 Float_t dt=0;
12788 Float_t nsig=0;
12789 Float_t nsigmax=0;
12790 Float_t nbkg=0;
12791 Float_t nbkgmax=0;
12792
12793 if (hSigNuCountProfile && fSigEmode!="SigE") // Signal neutrino events
12794 {
12795 axis=hSigNuCountProfile->GetYaxis();
12796 nbins=axis->GetNbins();
12797 jbin=axis->FindFixBin(cos(thetagrb));
12798
12799 if (jbin<1 || jbin>nbins) return;
12800
12801 nsigmax=0;
12802 nbins=hSigNuCountProfile->GetNbinsX();
12803 for (Int_t ibin=1; ibin<=nbins; ibin++)
12804 {
12805 nsig=hSigNuCountProfile->GetBinContent(ibin,jbin);
12806 if (nsig>nsigmax) nsigmax=nsig;
12807 }
12808
12809 dt=fDtwin*fTfact; // The specified source Flux or Intensity is regarded for a constant rate during the whole observational time window
12810 if (fSigEmode=="SigF") nsigmax=nsigmax*dt;
12811 if (fSigEmode=="SigI") nsigmax=nsigmax*dt*fOmegaDecl; // The source intensity represents part of a diffuse flux
12812 sx->AddNamedSlot("nsigmax");
12813 sx->SetSignal(nsigmax,"nsigmax");
12814 }
12815
12816 if (hBkgNuCountProfile && fBkgEmode!="BkgE") // Background neutrino events
12817 {
12818 axis=hBkgNuCountProfile->GetYaxis();
12819 nbins=axis->GetNbins();
12820 jbin=axis->FindFixBin(cos(thetagrb));
12821
12822 if (jbin<1 || jbin>nbins) return;
12823
12824 nbkgmax=0;
12825 nbins=hBkgNuCountProfile->GetNbinsX();
12826 for (Int_t ibin=1; ibin<=nbins; ibin++)
12827 {
12828 nsig=hBkgNuCountProfile->GetBinContent(ibin,jbin);
12829 if (nbkg>nbkgmax) nbkgmax=nsig;
12830 }
12831
12832 dt=fDtwin*fTfact; // The background is recorded during the complete observational time window
12833 if (fBkgEmode=="BkgF") nbkgmax=nbkgmax*dt;
12834 if (fBkgEmode=="BkgI") nbkgmax=nbkgmax*dt*fOmegaDecl; // The intensity represents a diffuse flux
12835 sx->AddNamedSlot("nbkgmax");
12836 sx->SetSignal(nbkgmax,"nbkgmax");
12837 }
12838}
12839
12840void NcAstrolab::MakeBurstZdist(TString file,TString tree,TString name,Int_t nb,Float_t zmin,Float_t zmax)
12841{
12873
12874 // The Tree containing the archival data
12875 TChain data(tree.Data());
12876 data.Add(file.Data());
12877
12878 Int_t nen=data.GetEntries();
12879 TLeaf* lx=data.FindLeaf(name.Data());
12880
12881 if (!nen || !lx)
12882 {
12883 cout << " *" << ClassName() << "::MakeBurstZdist* Missing information for tree variable:" << name << endl;
12884 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
12885 return;
12886 }
12887
12888 // Create new distributions in case a redshift distribution is not yet present
12889 TH1* zdist=(TH1*)fBurstHistos.FindObject("hz");
12890 if (!zdist)
12891 {
12892 // Creation of the archival burst redshift histogram
12893 TH1F* hz=new TH1F("hz","Archival data of observed burst redshifts",nb,zmin,zmax);
12894 fBurstHistos.Add(hz);
12895 hz->GetXaxis()->SetTitle("Burst redshift");
12896 hz->GetYaxis()->SetTitle("Counts");
12897
12898 // Creation of the corresponding physical distance histo
12899 Float_t dmin=GetPhysicalDistance(zmin);
12900 Float_t dmax=GetPhysicalDistance(zmax);
12901 TH1F* hd=new TH1F("hd","Burst distances derived from the archival redshift data",nb,dmin,dmax);
12902 fBurstHistos.Add(hd);
12903 hd->GetXaxis()->SetTitle("Burst physical distance in Mpc");
12904 hd->GetYaxis()->SetTitle("Counts");
12905 }
12906
12907 // Get pointers to the relevant histograms
12908 TH1* hz=(TH1*)fBurstHistos.FindObject("hz");
12909 TH1* hd=(TH1*)fBurstHistos.FindObject("hd");
12910
12911 Int_t nz=0;
12912 Double_t z=0;
12913 Double_t d=0;
12914 for (Int_t ien=0; ien<nen; ien++)
12915 {
12916 data.GetEntry(ien);
12917
12918 lx=data.GetLeaf(name.Data());
12919 if (!lx) continue;
12920
12921 z=lx->GetValue();
12922 if (z<zmin || z>zmax) continue;
12923
12924 hz->Fill(z);
12925 nz++;
12926
12928 hd->Fill(d);
12929 }
12930
12931 cout << " *" << ClassName() << "::MakeBurstZdist* " << nz << " archival z-values have been obtained from tree variable:" << name
12932 << " of Tree:" << tree << " in file(s):" << file << endl;
12933}
12934
12935TH1* NcAstrolab::GetBurstZdist(TString name,TString type)
12936{
12945
12946 TH1* zdist=(TH1*)fBurstHistos.FindObject("hz");
12947 if (!zdist)
12948 {
12949 if (type.Contains("GRB"))
12950 {
12951 cout << endl;
12952 cout << " *" << ClassName() << "::GetBurstZdist* Called from " << name << endl;
12953 cout << " *** Archival observed redshift distribution not found. ***" << endl;
12954 cout << " A Landau fit from Swift GRB redshift data will be used to provide missing c.q. random z values." << endl;
12955
12956 zdist=(TH1*)fBurstHistos.FindObject("hZpdf");
12957 if (!zdist)
12958 {
12959 TF1 fz("fz","59.54*TMath::Landau(x,1.092,0.5203)");
12960 fz.SetRange(0,10);
12961 fz.SetNpx(10000);
12962 TH1* hfz=fz.GetHistogram();
12963 zdist=(TH1*)hfz->Clone();
12964 zdist->SetNameTitle("hZpdf","Landau fit for Swift GRB z data");
12965 zdist->GetXaxis()->SetTitle("GRB redshift");
12966 zdist->GetYaxis()->SetTitle("Counts");
12967 fBurstHistos.Add(zdist);
12968 }
12969 }
12970 else // Source class for which no fit is available
12971 {
12972 cout << endl;
12973 cout << " *" << ClassName() << "::GetBurstZdist* Called from " << name << endl;
12974 cout << " *** No redshift fit is available for source class " << type << " ***" << endl;
12975 }
12976 }
12977
12978 return zdist;
12979}
12980
12981void NcAstrolab::MakeBurstT90dist(TString file,TString tree,TString name,Int_t nb,Float_t xmin,Float_t xmax)
12982{
13012
13013 // The Tree containing the burst data
13014 TChain data(tree.Data());
13015 data.Add(file.Data());
13016
13017 Int_t nen=data.GetEntries();
13018 TLeaf* lx=data.FindLeaf(name.Data());
13019
13020 if (!nen || !lx)
13021 {
13022 cout << " *" << ClassName() << "::MakeBurstT90dist* Missing information for tree variable:" << name << endl;
13023 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
13024 return;
13025 }
13026
13027 // Create a new distribution in case a T90 distribution is not yet present
13028 TH1* t90dist=(TH1*)fBurstHistos.FindObject("ht90");
13029 if (!t90dist)
13030 {
13031 // Creation of observed burst t90 duration histo
13032 TH1F* ht90=new TH1F("ht90","Archival data of observed burst durations",nb,xmin,xmax);
13033 fBurstHistos.Add(ht90);
13034 ht90->GetXaxis()->SetTitle("Burst duration ^{10}log(T90) in sec.");
13035 ht90->GetYaxis()->SetTitle("Counts");
13036 }
13037
13038 // Get pointer to the relevant histogram
13039 TH1* ht90=(TH1*)fBurstHistos.FindObject("ht90");
13040
13041 Int_t nt90=0;
13042 Double_t t90=0;
13043 for (Int_t ien=0; ien<nen; ien++)
13044 {
13045 data.GetEntry(ien);
13046
13047 lx=data.GetLeaf(name.Data());
13048 if (!lx) continue;
13049
13050 t90=lx->GetValue();
13051 if (t90>0)
13052 {
13053 ht90->Fill(log10(t90));
13054 nt90++;
13055 }
13056 }
13057
13058 cout << " *" << ClassName() << "::MakeBurstT90dist* " << nt90 << " archival T90 values have been obtained from variable:" << name
13059 << " of Tree:" << tree << " in file(s):" << file << endl;
13060}
13061
13062TH1* NcAstrolab::GetBurstT90dist(TString name,TString type)
13063{
13072
13073 TH1* t90dist=(TH1*)fBurstHistos.FindObject("ht90");
13074 if (!t90dist)
13075 {
13076 if (type.Contains("GRB"))
13077 {
13078 cout << endl;
13079 cout << " *" << ClassName() << "::GetBurstT90dist* Called from " << name << endl;
13080 cout << " *** Observational T90 distribution not found. ***" << endl;
13081 cout << " A double Gaussian fit from Fermi GRB T90 data will be used to provide missing c.q. random T90 values." << endl;
13082
13083 t90dist=(TH1*)fBurstHistos.FindObject("hT90pdf");
13084 if (!t90dist)
13085 {
13086 TF1 ft("ft","44.39*TMath::Gaus(x,-0.131,0.481)+193.8*TMath::Gaus(x,1.447,0.4752)");
13087 ft.SetRange(-5,5);
13088 ft.SetNpx(10000);
13089 TH1* hft=ft.GetHistogram();
13090 t90dist=(TH1*)hft->Clone();
13091 t90dist->SetNameTitle("hT90pdf","Double Gauss fit for Fermi t90 data");
13092 t90dist->GetXaxis()->SetTitle("GRB duration ^{10}log(T90) in sec.");
13093 t90dist->GetYaxis()->SetTitle("Counts");
13094 fBurstHistos.Add(t90dist);
13095 }
13096 }
13097 else // Source class for which no fit is available
13098 {
13099 cout << endl;
13100 cout << " *" << ClassName() << "::GetBurstT90dist* Called from " << name << endl;
13101 cout << " *** No T90 fit is available for source class " << type << " ***" << endl;
13102 }
13103 }
13104
13105 return t90dist;
13106}
13107
13108void NcAstrolab::MakeBurstSigmaPosdist(TString file,TString tree,TString name,TString u,Int_t nb,Float_t xmin,Float_t xmax)
13109{
13148
13149 // The Tree containing the burst data
13150 TChain data(tree.Data());
13151 data.Add(file.Data());
13152
13153 Int_t nen=data.GetEntries();
13154 TLeaf* lx=data.FindLeaf(name.Data());
13155
13156 if (!nen || !lx)
13157 {
13158 cout << " *" << ClassName() << "::MakeBurstSigmaPosdist* Missing information for tree variable:" << name << endl;
13159 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
13160 return;
13161 }
13162
13163 // Create a new distribution in case a burst position uncertainty distribution is not yet present
13164 TH1* sigmaposdist=(TH1*)fBurstHistos.FindObject("hsigmapos");
13165 if (!sigmaposdist)
13166 {
13167 // Creation of observed 1-sigma burst position uncertainty histo
13168 TH1F* hsigmapos=new TH1F("hsigmapos","Archival data of observed 1-sigma burst position uncertainties",nb,xmin,xmax);
13169 fBurstHistos.Add(hsigmapos);
13170 hsigmapos->GetXaxis()->SetTitle("Burst position uncertainty (sigma in degrees)");
13171 hsigmapos->GetYaxis()->SetTitle("Counts");
13172 }
13173
13174 // Get pointer to the relevant histogram
13175 TH1* hsigmapos=(TH1*)fBurstHistos.FindObject("hsigmapos");
13176
13177 Int_t nsigmapos=0;
13178 Double_t sigmapos=0;
13179 for (Int_t ien=0; ien<nen; ien++)
13180 {
13181 data.GetEntry(ien);
13182
13183 lx=data.GetLeaf(name.Data());
13184 if (!lx) continue;
13185
13186 sigmapos=lx->GetValue();
13187
13188 // Convert declination to degrees if needed
13189 sigmapos=ConvertAngle(sigmapos,u,"deg");
13190
13191 if (sigmapos<xmin || sigmapos>xmax) continue;
13192
13193 hsigmapos->Fill(sigmapos);
13194 nsigmapos++;
13195 }
13196
13197 cout << " *" << ClassName() << "::MakeBurstSigmaPosdist* " << nsigmapos << " archival sigmapos values have been obtained from variable:" << name
13198 << " of Tree:" << tree << " in file(s):" << file << endl;
13199}
13200
13201TH1* NcAstrolab::GetBurstSigmaPosdist(TString name,TString type)
13202{
13211
13212 TH1* sigmaposdist=(TH1*)fBurstHistos.FindObject("hsigmapos");
13213 if (!sigmaposdist)
13214 {
13215 if (type.Contains("GRB"))
13216 {
13217 cout << endl;
13218 cout << " *" << ClassName() << "::GetBurstSigmaPosdist* Called from " << name << endl;
13219 cout << " *** Archival observed GRB position uncertainty distribution not found. ***" << endl;
13220 cout << " A Landau fit from observed GRB data will be used to provide missing c.q. random 1-sigma uncertainty values." << endl;
13221
13222 sigmaposdist=(TH1*)fBurstHistos.FindObject("hSigmaSourcePDF");
13223 if (!sigmaposdist)
13224 {
13225 TF1 fsigmapos("fsigmapos","245.2*TMath::Landau(x,-2.209,0.6721,1)");
13226 fsigmapos.SetRange(0,90);
13227 fsigmapos.SetNpx(10000);
13228 TH1* hfsigmapos=fsigmapos.GetHistogram();
13229 sigmaposdist=(TH1*)hfsigmapos->Clone();
13230 sigmaposdist->SetNameTitle("hSigmaSourcePDF","Landau fit for burst 1-sigma position uncertainty data");
13231 sigmaposdist->GetXaxis()->SetTitle("Burst position uncertainty (sigma in degrees)");
13232 sigmaposdist->GetYaxis()->SetTitle("Counts");
13233 fBurstHistos.Add(sigmaposdist);
13234 }
13235 }
13236 else // Source class for which no fit is available
13237 {
13238 cout << endl;
13239 cout << " *" << ClassName() << "::GetBurstSigmaPosdist* Called from " << name << endl;
13240 cout << " *** No position uncertainty fit is available for source class " << type << " ***" << endl;
13241 }
13242 }
13243
13244 return sigmaposdist;
13245}
13246
13247void NcAstrolab::MakeBurstEnergydist(TString mode,TF1& spec,Int_t nsrc,Int_t nbins)
13248{
13322
13323 if (mode!="SigE" && mode!="SigS" && mode!="SigF" && mode!="SigI" && mode!="BkgE" && mode!="BkgS" && mode!="BkgF" && mode!="BkgI")
13324 {
13325 printf("\n *%-s::MakeBurstEnergydist* Inconsistent mode : %-s \n",ClassName(),mode.Data());
13326 return;
13327 }
13328
13329 // Set the corresponding energy boudaries
13330 Float_t fESigmin=fBurstParameters->GetSignal("ESigmin");
13331 Float_t fESigmax=fBurstParameters->GetSignal("ESigmax");
13332 Float_t fEmin=fBurstParameters->GetSignal("Emin");
13333 Float_t fEmax=fBurstParameters->GetSignal("Emax");
13334
13335 Float_t Emin=0;
13336 Float_t Emax=0;
13337 if (mode.Contains("Sig"))
13338 {
13339 Emin=fESigmin;
13340 Emax=fESigmax;
13341 }
13342 else
13343 {
13344 Emin=fEmin;
13345 Emax=fEmax;
13346 }
13347
13348 if (Emin<=0) Emin=1e-10;
13349
13350 // For background spectra and mode="SigE" the value of nsrc is irrelevant
13351 if (mode.Contains("Bkg") || mode=="SigE") nsrc=1;
13352
13353 if (Emax<=Emin || nbins<1 || nsrc<1)
13354 {
13355 printf("\n *%-s::MakeBurstEnergydist* Inconsistent data : mode=%-s nsrc=%-i Emin=%-g Emax=%-g nbins=%-i \n",ClassName(),mode.Data(),nsrc,Emin,Emax,nbins);
13356 return;
13357 }
13358
13359 // Convert the energy boundaries to the log10 scale of the X-axis
13360 Double_t xmin=log10(Emin);
13361 Double_t xmax=log10(Emax);
13362
13363 // Normalize the Fluence, Flux or Intensity to a single source (if needed)
13364 TString sf="";
13365 Float_t norm=1;
13366 if (nsrc>1 && (mode=="SigS" || mode=="BkgS"))
13367 {
13368 norm=1./float(nsrc);
13369 sf.Form("%-g*%-s",norm,(spec.GetExpFormula("p")).Data());
13370 }
13371 else
13372 {
13373 sf=spec.GetExpFormula("p");
13374 }
13375
13376 // The spectral function normalized (if needed) to a single source
13377 TF1 spec2("spec2",sf);
13378
13379 // Store the normalized spectral function
13380 if (mode.Contains("Sig")) fSigEprofile=spec2;
13381 if (mode.Contains("Bkg")) fBkgEprofile=spec2;
13382
13383 if (mode=="SigE" || mode=="BkgE")
13384 {
13385 sf="PDF for dN/dE=";
13386 sf+=spec2.GetExpFormula("p");
13387 norm=spec2.Integral(xmin,xmax);
13388 }
13389 else
13390 {
13391 sf="Counts cm^{-2}";
13392 if (mode.Contains("F")) sf+=" s^{-1}";
13393 if (mode.Contains("I")) sf+=" s^{-1} sr^{ -1}";
13394 sf+=" for dN/dE=";
13395 sf+=spec2.GetExpFormula("p");
13396 }
13397 sf.ReplaceAll("x","E");
13398 TString sh="";
13399 if (mode.Contains("Bkg")) sh="Isotropic background energy distribution at Earth";
13400 if (mode.Contains("Sig"))
13401 {
13402 if (mode=="SigE")
13403 {
13404 sh="Induced signal energy distribution at the source";
13405 }
13406 else
13407 {
13408 sh="Average per source induced signal energy distribution at Earth";
13409 }
13410 }
13411 sh+=";^{10}log(E) in GeV;";
13412 sh+=sf;
13413 TH1F his=GetCountsHistogram(spec2,nbins,xmin,xmax,1,sh);
13414
13415 // Remove the corresponding old distribution (if any) from the storage
13416 TH1* dist=0;
13417 if (mode.Contains("Bkg")) dist=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
13418 if (mode.Contains("Sig")) dist=(TH1*)fBurstHistos.FindObject("hSigEprofile");
13419 if (dist)
13420 {
13421 fBurstHistos.Remove(dist);
13422 fBurstHistos.Compress();
13423 delete dist;
13424 dist=0;
13425 }
13426
13427 // Store the newly created distribution
13428 // and set a flag to indicate a parametrized distribution
13429 if (mode.Contains("Bkg"))
13430 {
13431 fBkgEmode=mode;
13432 TH1F* hBkgEprofile=(TH1F*)his.Clone("hBkgEprofile");
13433 if (mode=="BkgE") hBkgEprofile->Scale(1./norm);
13434 fBurstHistos.Add(hBkgEprofile);
13435 fBurstParameters->AddNamedSlot("PDFbkgE");
13436 fBurstParameters->SetSignal(1,"PDFbkgE");
13437 }
13438 if (mode.Contains("Sig"))
13439 {
13440 fSigEmode=mode;
13441 TH1F* hSigEprofile=(TH1F*)his.Clone("hSigEprofile");
13442 if (mode=="SigE") hSigEprofile->Scale(1./norm);
13443 fBurstHistos.Add(hSigEprofile);
13444 fBurstParameters->AddNamedSlot("PDFsigE");
13445 fBurstParameters->SetSignal(1,"PDFsigE");
13446 }
13447
13448 printf("\n *%-s::MakeBurstEnergydist* Created a %-s profile %-s on [Emin,Emax]=[%-g,%-g] GeV \n",ClassName(),mode.Data(),sf.Data(),Emin,Emax);
13449
13450 // Create the corresponding NuCount and Zenith profile by using the Effective Area data (if any)
13452}
13453
13454void NcAstrolab::MakeBurstEnergydist(TString mode,Double_t alpha,Int_t nbins)
13455{
13489
13490 if (mode!="SigE" && mode!="BkgE")
13491 {
13492 printf(" *%-s::MakeBurstEnergydist* Unsupported mode : %-s for only spectral index specification \n",ClassName(),mode.Data());
13493 return;
13494 }
13495
13496 TF1 spec("spec","pow(x,[0])");
13497 spec.SetParameter(0,-alpha);
13498 MakeBurstEnergydist(mode,spec,0,nbins);
13499}
13500
13501void NcAstrolab::MakeBurstEnergydist(Int_t mode,TString file,TString tree,TString name1,TString name2,TString u,Int_t nb)
13502{
13559
13560 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
13561 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
13562
13563 Float_t fESigmin=fBurstParameters->GetSignal("ESigmin");
13564 Float_t fESigmax=fBurstParameters->GetSignal("ESigmax");
13565 Float_t fEmin=fBurstParameters->GetSignal("Emin");
13566 Float_t fEmax=fBurstParameters->GetSignal("Emax");
13567
13568 Float_t Emin=0;
13569 Float_t Emax=0;
13570 if (abs(mode)==2)
13571 {
13572 Emin=fESigmin;
13573 Emax=fESigmax;
13574 }
13575 else
13576 {
13577 Emin=fEmin;
13578 Emax=fEmax;
13579 }
13580
13581 if (Emin<=0) Emin=1e-10;
13582
13583 if ((abs(mode)!=1 && abs(mode)!=2) || Emax<=Emin)
13584 {
13585 printf(" *%-s::MakeBurstEnergydist* Inconsistent data: mode=%-i Emin=%-g Emax=%-g \n",ClassName(),mode,Emin,Emax);
13586 return;
13587 }
13588
13589 // Convert the energy boundaries to the log10 scale of the X-axis
13590 Double_t xmin=log10(Emin);
13591 Double_t xmax=log10(Emax);
13592
13593 // The Tree containing the burst data
13594 TChain data(tree.Data());
13595 data.Add(file.Data());
13596
13597 Int_t nen=data.GetEntries();
13598
13599 if (!nen || !data.FindLeaf(name1.Data()) || !data.FindLeaf(name2.Data()))
13600 {
13601 cout << " *" << ClassName() << "::MakeBurstEnergydist* Missing information for tree variable:" << name1
13602 << " and/or tree variable:" << name2 << endl;
13603 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
13604 return;
13605 }
13606
13607 // A corresponding parametrized distribution will always be removed
13608 Int_t flag=0;
13609 if (abs(mode)==1) flag=TMath::Nint(fBurstParameters->GetSignal("PDFbkgE"));
13610 if (abs(mode)==2) flag=TMath::Nint(fBurstParameters->GetSignal("PDFsigE"));
13611
13612 if (flag) mode=abs(mode);
13613
13614 // Remove the corresponding old distribution (if requested) from the storage
13615 TH1* Edist=0;
13616 if (abs(mode)==1) Edist=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
13617 if (abs(mode)==2) Edist=(TH1*)fBurstHistos.FindObject("hSigEprofile");
13618
13619 if (mode>0 && Edist)
13620 {
13621 fBurstHistos.Remove(Edist);
13622 fBurstHistos.Compress();
13623 delete Edist;
13624 Edist=0;
13625 }
13626
13627 // Create a new distribution if needed
13628 if (!Edist)
13629 {
13630 mode=abs(mode);
13631 if (mode==1)
13632 {
13633 // Creation of the observed background energy histo
13634 fBkgEmode="BkgE";
13635 TH1F* hBkgEprofile=new TH1F("hBkgEprofile","Archival data of observed background energies",nb,xmin,xmax);
13636 fBurstHistos.Add(hBkgEprofile);
13637 hBkgEprofile->GetXaxis()->SetTitle("^{10}log(Energy) in GeV");
13638 hBkgEprofile->GetYaxis()->SetTitle("Counts");
13639 fBurstParameters->AddNamedSlot("PDFbkgE");
13640 fBurstParameters->SetSignal(0,"PDFbkgE");
13641 }
13642 if (mode==2)
13643 {
13644 // Creation of the observed signal energy histo
13645 fSigEmode="SigE";
13646 TH1F* hSigEprofile=new TH1F("hSigEprofile","Archival data of observed signal energies",nb,xmin,xmax);
13647 fBurstHistos.Add(hSigEprofile);
13648 hSigEprofile->GetXaxis()->SetTitle("^{10}log(Energy) in GeV");
13649 hSigEprofile->GetYaxis()->SetTitle("Counts");
13650 fBurstParameters->AddNamedSlot("PDFsigE");
13651 fBurstParameters->SetSignal(0,"PDFsigE");
13652 fBurstParameters->SetSignal(0,"Ezcor");
13653 }
13654 }
13655
13656 // Get pointer to the relevant histogram
13657 if (abs(mode)==1) Edist=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
13658 if (abs(mode)==2) Edist=(TH1*)fBurstHistos.FindObject("hSigEprofile");
13659
13660 Int_t nE=0;
13661 Double_t logE=0;
13662 Double_t dec=0;
13663 TLeaf* lx=0;
13664 for (Int_t ien=0; ien<nen; ien++)
13665 {
13666 data.GetEntry(ien);
13667
13668 lx=data.GetLeaf(name1.Data());
13669 if (!lx) continue;
13670
13671 logE=lx->GetValue();
13672
13673 lx=data.GetLeaf(name2.Data());
13674 if (!lx) continue;
13675
13676 dec=lx->GetValue();
13677
13678 // Convert declination to degrees if needed
13679 dec=ConvertAngle(dec,u,"deg");
13680
13681 if (dec>=fDeclmin && dec<=fDeclmax)
13682 {
13683 Edist->Fill(logE);
13684 nE++;
13685 }
13686 }
13687
13688 TString smode="";
13689 if (abs(mode)==1) smode="archival background";
13690 if (abs(mode)==2) smode="archival signal";
13691
13692 if (mode>0)
13693 {
13694 cout << " *" << ClassName() << "::MakeBurstEnergydist* A new " << smode
13695 << " energy distribution has been created." << endl;
13696 }
13697 else
13698 {
13699 cout << " *" << ClassName() << "::MakeBurstEnergydist* Statistics of the existing " << smode
13700 << " energy distribution have been increased." << endl;
13701 }
13702
13703 cout << " " << nE << " energy values have been obtained from variable:" << name1
13704 << " of Tree:" << tree << " in file(s):" << file << endl;
13705}
13706
13707void NcAstrolab::MakeBurstRecoAngresdist(TString file,TString tree,TString name1,TString name2,TString ua,TString name3,TString ud,Double_t Emin,Double_t Emax,Int_t nbe,Int_t nba)
13708{
13756
13757 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
13758 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
13759
13760 if (Emin<=0) Emin=1e-10;
13761
13762 if (Emax<=Emin)
13763 {
13764 cout << " *" << ClassName() << "::MakeBurstRecoAngresdist* Inconsistent data: Emin=" << Emin << " Emax=" << Emax << endl;
13765 return;
13766 }
13767
13768 // Convert the energy boundaries to the log10 scale of the X-axis
13769 Double_t xmin=log10(Emin);
13770 Double_t xmax=log10(Emax);
13771
13772 // The Tree containing the burst data
13773 TChain data(tree.Data());
13774 data.Add(file.Data());
13775
13776 Int_t nen=data.GetEntries();
13777
13778 if (!nen || !data.FindLeaf(name1.Data()) || !data.FindLeaf(name2.Data()) || !data.FindLeaf(name3.Data()))
13779 {
13780 cout << " *" << ClassName() << "::MakeBurstRecoAngresdist* Missing information for tree variable:" << name1
13781 << " and/or tree variable:" << name2 << " and/or tree variable:" << name3 << endl;
13782 cout << " of Tree:" << tree << " with " << nen << " entries in file:" << file << endl;
13783 return;
13784 }
13785
13786 // Create a new distribution in case a reconstruction angle resolution vs. energy distribution is not yet present
13787 TH2* Angresdist=(TH2*)fBurstHistos.FindObject("hAngresE");
13788 if (!Angresdist)
13789 {
13790 // Creation of the observed reconstruction angle resolution vs. energy histo
13791 TH2F* hAngresE=new TH2F("hAngresE","Archival data of observed reconstruction angle resolution vs. energy",
13792 nbe,xmin,xmax,nba,0,180.1);
13793 fBurstHistos.Add(hAngresE);
13794 hAngresE->GetXaxis()->SetTitle("^{10}log(Energy) in GeV");
13795 hAngresE->GetYaxis()->SetTitle("Angular resolution in degrees");
13796 }
13797
13798 // Get pointer to the relevant histogram
13799 TH2* hAngresE=(TH2*)fBurstHistos.FindObject("hAngresE");
13800
13801 Int_t nE=0;
13802 Double_t logE=0;
13803 Double_t dec=0;
13804 Double_t dang=0;
13805 TLeaf* lx=0;
13806 for (Int_t ien=0; ien<nen; ien++)
13807 {
13808 data.GetEntry(ien);
13809
13810 lx=data.GetLeaf(name1.Data());
13811 if (!lx) continue;
13812
13813 logE=lx->GetValue();
13814
13815 lx=data.GetLeaf(name2.Data());
13816 if (!lx) continue;
13817
13818 dang=lx->GetValue();
13819
13820 // Convert declination to degrees if needed
13821 dang=ConvertAngle(dang,ua,"deg");
13822
13823 lx=data.GetLeaf(name3.Data());
13824 if (!lx) continue;
13825
13826 dec=lx->GetValue();
13827
13828 // Convert declination to degrees if needed
13829 dec=ConvertAngle(dec,ud,"deg");
13830
13831 if (dec>=fDeclmin && dec<=fDeclmax)
13832 {
13833 hAngresE->Fill(logE,dang);
13834 nE++;
13835 }
13836 }
13837
13838 cout << " *" << ClassName() << "::MakeBurstRecoAngresdist* " << nE << " archival entries have been obtained for variables:" << name2
13839 << " vs. " << name1 << " of Tree:" << tree << " in file(s):" << file << endl;
13840}
13841
13842Double_t NcAstrolab::GetBurstSignalEnergy(Double_t Emin,Double_t Emax) const
13843{
13861
13862 Double_t E=-1;
13863
13864 // Get pointer to the relevant histogram
13865 TH1* hSigEprofile=(TH1*)fBurstHistos.FindObject("hSigEprofile");
13866
13867 if (!hSigEprofile) return E;
13868
13869 Int_t nbins=hSigEprofile->GetNbinsX();
13870 Int_t nentries=hSigEprofile->GetEntries();
13871
13872 if (nbins<=0 || nentries<=0) return E;
13873
13874 TAxis* xaxis=hSigEprofile->GetXaxis();
13875
13876 if (!xaxis) return E;
13877
13878 Double_t xlow=xaxis->GetBinLowEdge(1);
13879 Double_t xup=xaxis->GetBinUpEdge(nbins);
13880
13881 Double_t logEmin=0;
13882 if (Emin<=0)
13883 {
13884 logEmin=xlow;
13885 }
13886 else
13887 {
13888 logEmin=log10(Emin);
13889 }
13890
13891 Double_t logEmax=0;
13892 if (Emax<=0)
13893 {
13894 logEmax=xup;
13895 }
13896 else
13897 {
13898 logEmax=log10(Emax);
13899 }
13900
13901 if (logEmax<=logEmin || logEmin>=xup || logEmax<=xlow) return E;
13902
13903 while (E<logEmin || E>logEmax)
13904 {
13905 E=hSigEprofile->GetRandom();
13906 }
13907
13908 E=pow(float(10),E);
13909
13910 return E;
13911}
13912
13913Double_t NcAstrolab::GetBurstBackgroundEnergy(Double_t Emin,Double_t Emax) const
13914{
13932
13933 Double_t E=-1;
13934
13935 // Get pointer to the relevant histogram
13936 TH1* hBkgEprofile=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
13937
13938 if (!hBkgEprofile) return E;
13939
13940 Int_t nbins=hBkgEprofile->GetNbinsX();
13941 Int_t nentries=hBkgEprofile->GetEntries();
13942
13943 if (nbins<=0 || nentries<=0) return E;
13944
13945 TAxis* xaxis=hBkgEprofile->GetXaxis();
13946
13947 if (!xaxis) return E;
13948
13949 Double_t xlow=xaxis->GetBinLowEdge(1);
13950 Double_t xup=xaxis->GetBinUpEdge(nbins);
13951
13952 Double_t logEmin=0;
13953 if (Emin<=0)
13954 {
13955 logEmin=xlow;
13956 }
13957 else
13958 {
13959 logEmin=log10(Emin);
13960 }
13961
13962 Double_t logEmax=0;
13963 if (Emax<=0)
13964 {
13965 logEmax=xup;
13966 }
13967 else
13968 {
13969 logEmax=log10(Emax);
13970 }
13971
13972 if (logEmax<=logEmin || logEmin>=xup || logEmax<=xlow) return E;
13973
13974 while (E<logEmin || E>logEmax)
13975 {
13976 E=hBkgEprofile->GetRandom();
13977 }
13978
13979 E=pow(float(10),E);
13980
13981 return E;
13982}
13983
13984Double_t NcAstrolab::GetBurstRecoAngres(Double_t Emin,Double_t Emax,Double_t Amin,Double_t Amax) const
13985{
14009
14010 Double_t dang=-1;
14011
14012 if (Amin<0) Amin=0;
14013
14014 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
14015 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
14016
14017 // The user requested a fixed angular resolution value "Angresfix"
14018 if (!fRecoangle)
14019 {
14020 dang=fAngresfix;
14021 return dang;
14022 }
14023
14024 // The user requested an angular resolution based on a distribution
14025
14026 // Get pointer to the reco angle resolution vs. energy distribution histogram
14027 TH2* hAngresE=(TH2*)fBurstHistos.FindObject("hAngresE");
14028
14029 // No distribution available -> Return the user provided "Angresfix" value
14030 if (!hAngresE)
14031 {
14032 dang=fAngresfix;
14033 return dang;
14034 }
14035
14036 // Obtain the projected reco angle resolution distribution within the [Emin,Emax] interval
14037
14038 Int_t nbins=hAngresE->GetNbinsX();
14039 Int_t nentries=hAngresE->GetEntries();
14040
14041 if (nbins<=0 || nentries<=0) return dang;
14042
14043 TAxis* xaxis=hAngresE->GetXaxis();
14044
14045 if (!xaxis) return dang;
14046
14047 Double_t xlow=xaxis->GetBinLowEdge(1);
14048 Double_t xup=xaxis->GetBinUpEdge(nbins);
14049
14050 Double_t logEmin=0;
14051 if (Emin<=0)
14052 {
14053 logEmin=xlow;
14054 }
14055 else
14056 {
14057 logEmin=log10(Emin);
14058 }
14059
14060 Double_t logEmax=0;
14061 if (Emax<=0)
14062 {
14063 logEmax=xup;
14064 }
14065 else
14066 {
14067 logEmax=log10(Emax);
14068 }
14069
14070 if (logEmax<logEmin || logEmin>=xup || logEmax<=xlow) return dang;
14071
14072 Int_t ilow=xaxis->FindBin(logEmin);
14073 Int_t iup=xaxis->FindBin(logEmax);
14074
14075 TH1D* hproj=hAngresE->ProjectionY("hproj",ilow,iup);
14076
14077 if (!hproj) return dang;
14078
14079 nbins=hproj->GetNbinsX();
14080 nentries=hproj->GetEntries();
14081
14082 if (nbins<=0 || nentries<=0) return dang;
14083
14084 if (fRecoangle==1) dang=hproj->GetMean();
14085
14086 if (fRecoangle==2)
14087 {
14088 NcSample q;
14089 dang=q.GetMedian(hproj);
14090 }
14091
14092 if (fRecoangle==3)
14093 {
14094 xaxis=hproj->GetXaxis();
14095
14096 if (!xaxis) return dang;
14097
14098 xlow=xaxis->GetBinLowEdge(1);
14099 xup=xaxis->GetBinUpEdge(nbins);
14100
14101 if (Amax<=Amin || Amin>=xup || Amax<=xlow) return dang;
14102
14103 dang=Amin-1.;
14104 while (dang<Amin || dang>Amax)
14105 {
14106 dang=hproj->GetRandom();
14107 }
14108 }
14109
14110 if (hproj) delete hproj;
14111
14112 return dang;
14113}
14114
14116{
14135
14136 // Signal and background generation can only be performed for a user defined fixed time window size
14137 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
14138 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
14139 if (fTmax<=fTmin)
14140 {
14141 printf("\n *%-s::GenBurstSignals* Error : [Tmin,Tmax]=[%-g,%-g] whereas Tmin<Tmax is required. \n",ClassName(),fTmin,fTmax);
14142 return;
14143 }
14144
14145 // If needed, initialise the randomiser with a "date/time driven" seed
14146 // using the timestamp of the moment of this invokation of the member function.
14147 // This will ensure different random sequences if the user repeats analyses
14148 // with identical measurements and reference signals without explicit initialisation
14149 // of the randomiser by the user at the start of the analysis.
14150 if (!fRan) fRan=new NcRandom(-1);
14151
14153 // Initialise the final sample histograms //
14155
14157
14158 // Retrieve the needed parameters
14159 Float_t fRAmin=fBurstParameters->GetSignal("RAmin");
14160 Float_t fRAmax=fBurstParameters->GetSignal("RAmax");
14161 Float_t fDeclmin=fBurstParameters->GetSignal("Declmin");
14162 Float_t fDeclmax=fBurstParameters->GetSignal("Declmax");
14163 Float_t fTimres=fBurstParameters->GetSignal("Timres");
14164 Int_t fEzcor=TMath::Nint(fBurstParameters->GetSignal("Ezcor"));
14165 Int_t fPDFsigE=TMath::Nint(fBurstParameters->GetSignal("PDFsigE"));
14166 Float_t fEmin=fBurstParameters->GetSignal("Emin");
14167 Float_t fEmax=fBurstParameters->GetSignal("Emax");
14168 Int_t fKinangle=TMath::Nint(fBurstParameters->GetSignal("Kinangle"));
14169 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
14170 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
14171 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
14172 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
14173 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
14174 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
14175 Float_t fDtwin=fBurstParameters->GetSignal("Dtwin");
14176 Float_t fDawin=fBurstParameters->GetSignal("Dawin");
14177 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
14178 Float_t fGrbnu=fBurstParameters->GetSignal("Grbnu");
14179 Int_t fInburst=TMath::Nint(fBurstParameters->GetSignal("Inburst"));
14180 Float_t fDtnu=fBurstParameters->GetSignal("Dtnu");
14181 Float_t fDtnus=fBurstParameters->GetSignal("Dtnus");
14182 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
14183
14184 // Deactivate redshift correction for source signal events from archival observed data
14185 if (!fPDFsigE)
14186 {
14187 fEzcor=0;
14188 fBurstParameters->SetSignal(0,"Ezcor");
14189 }
14190
14191 // Derived parameters
14192 Float_t fMaxsigmatot=fBurstParameters->GetSignal("Maxsigmatot");
14193 Float_t fNbkgWin=fBurstParameters->GetSignal("NbkgWin");
14194
14196 // Some Burst statistics from the loaded data //
14198
14199 Int_t fNgrbs=GetNsignals(0);
14200
14201 TH1* hSigmaReco=(TH1*)fBurstHistos.FindObject("hSigmaReco");
14202 TH1* hSigE=(TH1*)fBurstHistos.FindObject("hSigE");
14203 TH1* hSigEzcor=(TH1*)fBurstHistos.FindObject("hSigEzcor");
14204 TH2* hAeffProfile=(TH2*)fBurstHistos.FindObject("hAeffProfile");
14205 TH2* hSigNuCountProfile=(TH2*)fBurstHistos.FindObject("hSigNuCountProfile");
14206 TH2* hBkgNuCountProfile=(TH2*)fBurstHistos.FindObject("hBkgNuCountProfile");
14207
14209 // Generation of the signal and background observations //
14210 // based on the provided user settings //
14212
14213 NcSignal* sx=0;
14214 Float_t zgrb=0;
14215 Double_t dgrb=0;
14216 Float_t t90grb=0;
14217 Float_t sigmagrb=0;
14218 NcPosition rgrb;
14219 Float_t nbkgmax=0; // The maximum number of recordable background neutrino events for the treated GRB
14220 Float_t nbkg=0; // The mean number of recordable background events in the time window for the treated GRB
14221 Float_t nsigmax=0; // The maximum number of recordable signal events for the treated GRB
14222 Float_t nsig=0; // The mean number of recordable signal events for the treated GRB
14223 Int_t nmu;
14224 Double_t thetagrb,phigrb;
14225 Double_t dmu,thetamu,phimu;
14226 Float_t dt=0;
14227 NcPosition rgrb2; // Unknown actual GRB position from which the neutrinos/muons arrive
14228 NcPosition rmu;
14229 Float_t dang;
14230 Float_t dangmax=0;
14231 Float_t dangmaxon=0;
14232 Float_t dangmaxoff=0;
14233 Float_t thlow,thup;
14234 Float_t ranlow,ranup;
14235 Int_t nmugrb=0;
14236 NcTimestamp* tx=0;
14237 NcTimestamp tmu;
14238 Float_t solidangle=0;
14239 Float_t ramu,decmu; // Temporary RA and DEC of muon for background creation
14240 Double_t E=0;
14241 Double_t ang=0;
14242 Double_t sigmareco=0;
14243 Float_t sigmatot=0;
14244 TString name;
14245 Int_t fixedwinset=0; // Flag to indicate whether a fixed angular search window is set (1) or not (0) for this burst
14246
14247 // Storage for total on-source and off-source observed and signal injected energies
14248 fBurstParameters->AddNamedSlot("EnergyOn");
14249 fBurstParameters->AddNamedSlot("EnergyOff");
14250 fBurstParameters->AddNamedSlot("EnergySig");
14251
14252 // The bin numbers and Aeff value in the AeffProfile for the (E,theta) of the track
14253 Int_t nbinsA=0;
14254 if (hAeffProfile) nbinsA=(hAeffProfile->GetNbinsX())*(hAeffProfile->GetNbinsY());
14255 Int_t nbinsCsig=0;
14256 if (hSigNuCountProfile) nbinsCsig=(hSigNuCountProfile->GetNbinsX())*(hSigNuCountProfile->GetNbinsY());
14257 Int_t nbinsCbkg=0;
14258 if (hBkgNuCountProfile) nbinsCbkg=(hBkgNuCountProfile->GetNbinsX())*(hBkgNuCountProfile->GetNbinsY());
14259 Int_t gbin=0; // The global bin number in the histogram
14260 Double_t Aeff=0;
14261 Double_t Fluence=0;
14262
14263 Double_t pi=acos(-1.);
14264
14265 // Loop over the (fictative) GRB space-time positions in the declination acceptance
14266 for (Int_t igrb=0; igrb<fNgrbs; igrb++)
14267 {
14268 sx=GetSignal(igrb+1);
14269
14270 if (!sx) continue;
14271
14272 tx=sx->GetTimestamp();
14273 zgrb=sx->GetSignal("z");
14274 t90grb=sx->GetSignal("T90");
14275 sigmagrb=sx->GetSignal("csigma");
14276 GetSignal(dgrb,thetagrb,"deg",phigrb,"deg","loc",tx,igrb+1);
14277 rgrb.SetPosition(1,thetagrb,phigrb,"sph","deg");
14278
14279 dangmax=-1;
14280 if (!fDatype) dangmax=fabs(fDawin);
14281 if (fDatype==1)
14282 {
14283 dangmax=0;
14284 if (fMaxsigmatot>0) dangmax=fabs(fDawin*fMaxsigmatot);
14285 }
14286
14287 if (fDatype==2)
14288 {
14289 if (!fSumsigmas) dangmax=fabs(fDawin*sigmagrb);
14290 if (!fRecoangle)
14291 {
14292 sigmatot=-1;
14293 if (fSumsigmas==-1) sigmatot=fAngresfix;
14294 if (fSumsigmas==1) sigmatot=sigmagrb+fAngresfix;
14295 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+fAngresfix*fAngresfix);
14296 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
14297 }
14298 }
14299
14300 fixedwinset=1;
14301 if (dangmax<0) fixedwinset=0;
14302
14303 // Indicate incompatible input for sigma summation
14304 if (fDatype==1 && fMaxsigmatot<0) dangmax=-1;
14305
14306 // New signal slots for storage of maximum angular differences and corresponding solid angles
14307 name="fixedwinset";
14308 sx->AddNamedSlot(name);
14309 sx->SetSignal(fixedwinset,name);
14310 name="dangmaxOn";
14311 sx->AddNamedSlot(name);
14312 sx->SetSignal(-1,name);
14313 name="dangmaxOff";
14314 sx->AddNamedSlot(name);
14315 sx->SetSignal(-1,name);
14316 name="OmegaOn";
14317 sx->AddNamedSlot(name);
14318 sx->SetSignal(0,name);
14319 name="OmegaOff";
14320 sx->AddNamedSlot(name);
14321 sx->SetSignal(0,name);
14322
14323 // Store the On-source and Off-source maximum (solid) angles for this burst
14324 if (fixedwinset && dangmax>=0)
14325 {
14326 if (fDawin<0) // Local zenith band
14327 {
14328 thlow=thetagrb-0.5*dangmax;
14329 thup=thetagrb+0.5*dangmax;
14330 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14331 }
14332 else // Circle around GRB position
14333 {
14334 thlow=0;
14335 thup=dangmax;
14336 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14337 }
14338 sx->SetSignal(dangmax,"dangmaxOn");
14339 sx->SetSignal(solidangle,"OmegaOn");
14340 sx->SetSignal(dangmax,"dangmaxOff");
14341 sx->SetSignal(solidangle*float(fNbkg),"OmegaOff");
14342 }
14343 else // Initialize the encountered dynamic On-source and Off-source maximum angles for this burst
14344 {
14345 dangmaxon=0;
14346 if (fSumsigmas==0 || fSumsigmas==1 || fSumsigmas==2) dangmaxon=fabs(fDawin*sigmagrb);
14347 dangmaxoff=dangmaxon;
14348 }
14349
14350 // Generate the background events in the search time window
14351 // for both this GRB angular cone and the corresponding background bkg patch(es)
14352 for (Int_t bkgpatch=0; bkgpatch<=fNbkg; bkgpatch++)
14353 {
14354
14355 if (fBkgEmode=="BkgE") // Background rate set via user provided burst parameter "Bkgrate"
14356 {
14357 nbkg=fNbkgWin;
14358 nmu=int(fRan->Poisson(nbkg));
14359 }
14360 else // Neutrino background strength set via user provided Fluence, Flux or Intensity
14361 {
14362 nbkgmax=sx->GetSignal("nbkgmax");
14363 nmu=TMath::Nint(fRan->Poisson(nbkgmax));
14364 if (!hBkgNuCountProfile) nmu=0;
14365 }
14366
14367 for (Int_t imu=0; imu<nmu; imu++)
14368 {
14369 // Obtain a random event time within the search time window
14370 ranlow=fTmin;
14371 ranup=fTmax;
14372 dt=fRan->Uniform(ranlow,ranup);
14373
14374 // Create a random background event within the user selected burst RA and Dec interval
14375 // and convert to local detector coordinates to allow a local zenith band selection.
14376 // For the conversion, a single, re-usable temp. reference signal will be created, since measurements may get scrambled when stored.
14377 thlow=90.-fDeclmax; // Lower theta angle in overall Earth spherical coordinates (North Pole is theta=0)
14378 thup=90.-fDeclmin; // Upper theta angle in overall Earth spherical coordinates (North Pole is theta=0)
14379 RandomPosition(rmu,thlow,thup,fRAmin,fRAmax);
14380 decmu=90.-rmu.GetX(2,"sph","deg");
14381 ramu=rmu.GetX(3,"sph","deg");
14382 tmu=*tx;
14383 tmu.AddSec(dt*fTfact);
14384 SetSignal(1,ramu,"deg",decmu,"deg","equ",&tmu,fNgrbs+1,"J","bkgtemp",0);
14385 GetSignal(dmu,thetamu,"deg",phimu,"deg","loc",&tmu,fNgrbs+1);
14386 rmu.SetPosition(1,thetamu,phimu,"sph","deg");
14387
14388 if (fDawin<0) // Local zenith band
14389 {
14390 dang=fabs(thetagrb-thetamu);
14391 }
14392 else // Circle around GRB position
14393 {
14394 dang=rgrb.GetOpeningAngle(rmu,"deg");
14395 }
14396
14397 // Check if event lies outside the allowed angular area
14398 if (fDatype>=0 && fixedwinset && dang>dangmax) continue;
14399
14400 // The energy of the background signal
14402
14403 if (E<0 || E<fEmin || E>fEmax) continue;
14404
14405 if (fBkgEmode!="BkgE" && hBkgNuCountProfile)
14406 {
14407 nbkg=0;
14408 gbin=hBkgNuCountProfile->FindFixBin(log10(E),cos(thetagrb*pi/180.));
14409 if (gbin>0 && gbin<=nbinsCbkg) nbkg=hBkgNuCountProfile->GetBinContent(gbin);
14410 // A steady flux is assumed during the complete obervation time
14411 if (fBkgEmode!="BkgS") nbkg=nbkg*fDtwin*fTfact;
14412 if (nbkg>0) nbkg=fRan->Poisson(nbkg);
14413 if (nbkg<1) continue;
14414 }
14415
14416 // The reconstruction angular resolution of the background signal
14417 sigmareco=GetBurstRecoAngres(E,E);
14418 if (sigmareco<0) sigmareco=fAngresfix;
14419
14420 if (sigmareco<fAngresmin || sigmareco>fAngresmax) continue;
14421
14422 if (hSigmaReco) hSigmaReco->Fill(sigmareco);
14423
14424 sigmatot=-1;
14425 if (fSumsigmas==-1) sigmatot=sigmareco;
14426 if (fSumsigmas==0) sigmatot=sigmagrb;
14427 if (fSumsigmas==1) sigmatot=sigmagrb+sigmareco;
14428 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+sigmareco*sigmareco);
14429
14430 // Determine the dynamic angular window including the track reco uncertainty
14431 if (!fixedwinset)
14432 {
14433 dangmax=-1;
14434 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
14435 }
14436
14437 if (fDatype>=0 && dang>dangmax) continue;
14438
14439 if (!bkgpatch)
14440 {
14441 if (dangmax>dangmaxon) dangmaxon=dangmax;
14442 fBurstOnReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
14443 fBurstOnMatch.Enter(E,dt,dang,dt/(zgrb+1.));
14444 fBurstParameters->AddSignal(E,"EnergyOn");
14445 if (hAeffProfile)
14446 {
14447 thetamu=rmu.GetX(2,"sph","rad");
14448 gbin=hAeffProfile->FindFixBin(log10(E),cos(thetamu));
14449 if (gbin>0 && gbin<nbinsA+1)
14450 {
14451 Aeff=hAeffProfile->GetBinContent(gbin);
14452 if (Aeff>0)
14453 {
14454 Fluence=1./Aeff;
14455 fBurstOnAeff.Enter(Aeff,Fluence,E,dang);
14456 }
14457 }
14458 }
14459 }
14460 else
14461 {
14462 if (dangmax>dangmaxoff) dangmaxoff=dangmax;
14463 fBurstOffReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
14464 fBurstOffMatch.Enter(E,dt,dang,dt/(zgrb+1.));
14465 fBurstParameters->AddSignal(E,"EnergyOff");
14466 if (hAeffProfile)
14467 {
14468 thetamu=rmu.GetX(2,"sph","rad");
14469 gbin=hAeffProfile->FindFixBin(log10(E),cos(thetamu));
14470 if (gbin>0 && gbin<nbinsA+1)
14471 {
14472 Aeff=hAeffProfile->GetBinContent(gbin);
14473 if (Aeff>0)
14474 {
14475 Fluence=1./Aeff;
14476 fBurstOffAeff.Enter(Aeff,Fluence,E,dang);
14477 }
14478 }
14479 }
14480 }
14481 } // End of loop over the background tracks of this patch
14482 } // End of loop over the patches
14483
14484 // Generate the GRB related signal event(s) in the search window.
14485 // The GRB position gets Gaussian smeared to reflect the actual position.
14486 // The time difference between the gammas and the neutrinos gets corrected
14487 // for the GRB redshift and smeared by the detector time resolution.
14488 // The muon direction gets modified to account for the kinematical opening angle
14489 // w.r.t. the neutrino direction and Gaussian smeared by the detector angular resolution.
14490
14491 // Prevent statistical overfluctuation in number of GRB signal events if requested by fGrbnu<0
14492 if ((fSigEmode=="SigE" && (fGrbnu>=0 || nmugrb<int(fabs(fGrbnu)*float(fNgrbs)))) || fSigEmode!="SigE")
14493 {
14494 // Obtain actual GRB position
14495 rgrb2.Load(rgrb);
14496 SmearPosition(rgrb2,sigmagrb);
14497
14498 if (fSigEmode=="SigE") // Signal strength set via user provided burst parameter "Grbnu"
14499 {
14500 nmu=int(fabs(fGrbnu));
14501 if (!nmu && fRan->Uniform()<fabs(fGrbnu)) nmu=1;
14502 }
14503 else // Signal strength set via user provided Fluence, Flux or Intensity
14504 {
14505 nsigmax=sx->GetSignal("nsigmax");
14506 nmu=TMath::Nint(fRan->Poisson(nsigmax));
14507 if (!hSigNuCountProfile) nmu=0;
14508 }
14509
14510 for (Int_t imu=0; imu<nmu; imu++)
14511 {
14512 if (!fInburst) // Neutrino and gamma production decoupled
14513 {
14514 if (fDtnus<0) // Sigma in units of T90
14515 {
14516 dt=fRan->Gauss(fDtnu,fabs(fDtnus)*t90grb);
14517 }
14518 else // Sigma in seconds
14519 {
14520 dt=fRan->Gauss(fDtnu,fDtnus);
14521 }
14522 dt=dt*(zgrb+1.);
14523 }
14524 else // Coupled neutrino and gamma production
14525 {
14526 if (fDtnus<0) // Sigma in units of T90
14527 {
14528 dt=fRan->Gauss(fDtnu*t90grb,fabs(fDtnus)*t90grb);
14529 }
14530 else // Sigma in seconds
14531 {
14532 dt=fRan->Gauss(fDtnu*t90grb,fDtnus);
14533 }
14534 }
14535 if (fTimres>0) dt=fRan->Gauss(dt,fTimres);
14536
14537 // Convert dt from seconds to the selected Tunit
14538 dt=dt/fTfact;
14539
14540 // The direction of the GRB signal
14541 rmu.Load(rgrb2);
14542
14543 // The energy of the GRB signal
14545
14546 // Check for possible signal in case a Fluence, Flux or Intensity was specified
14547 if (fSigEmode!="SigE" && hSigNuCountProfile)
14548 {
14549 nsig=0;
14550 gbin=hSigNuCountProfile->FindFixBin(log10(E),cos(thetagrb*pi/180.));
14551 if (gbin>0 && gbin<=nbinsCsig) nsig=hSigNuCountProfile->GetBinContent(gbin);
14552 // A steady flux is assumed during the complete obervation time
14553 if (fSigEmode!="SigS") nsig=nsig*fDtwin*fTfact;
14554 if (nsig>0) nsig=fRan->Poisson(nsig);
14555 if (nsig<1) continue;
14556 }
14557
14558 nmugrb++;
14559
14560 if (fSigEmode=="SigE")
14561 {
14562 // Injected energy at the source
14563 if (hSigE) hSigE->Fill(E);
14564
14565 // Reduce the energy due to the cosmological redshift effect
14566 if (fEzcor) E=E/(zgrb+1.);
14567 }
14568
14569 if (hSigEzcor) hSigEzcor->Fill(E);
14570
14571 if (E<0 || E<fEmin || E>fEmax) continue;
14572
14573 // Modification to account for the neutrino-lepton kinematic opening angle
14574 if (fKinangle>0)
14575 {
14576 Int_t mode=fKinangle-1;
14577 ang=GetNeutrinoAngle(E,"deg",mode);
14578 if (ang>0) ShiftPosition(rmu,ang);
14579 }
14580
14581 // Smearing according to the reconstruction angular resolution
14582 sigmareco=GetBurstRecoAngres(E,E);
14583 if (sigmareco<0) sigmareco=fAngresfix;
14584
14585 if (sigmareco<fAngresmin || sigmareco>fAngresmax) continue;
14586
14587 if (hSigmaReco) hSigmaReco->Fill(sigmareco);
14588
14589 SmearPosition(rmu,sigmareco);
14590
14591 // Determine angular difference w.r.t. the presumed GRB position
14592 dang=rgrb.GetOpeningAngle(rmu,"deg");
14593
14594 sigmatot=-1;
14595 if (fSumsigmas==-1) sigmatot=sigmareco;
14596 if (fSumsigmas==0) sigmatot=sigmagrb;
14597 if (fSumsigmas==1) sigmatot=sigmagrb+sigmareco;
14598 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+sigmareco*sigmareco);
14599
14600 // Determine the dynamic angular window including the track reco uncertainty
14601 if (!fixedwinset)
14602 {
14603 dangmax=-1;
14604 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
14605 }
14606
14607 if (fDatype>=0 && dang>dangmax) continue;
14608
14609 if (dangmax>dangmaxon) dangmaxon=dangmax;
14610 fBurstOnReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
14611 fBurstOnMatch.Enter(E,dt,dang,dt/(zgrb+1.));
14612 fBurstSigReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
14613 fBurstSignal.Enter(E,dt,dang,dt/(zgrb+1.));
14614 fBurstParameters->AddSignal(E,"EnergyOn");
14615 fBurstParameters->AddSignal(E,"EnergySig");
14616 if (hAeffProfile)
14617 {
14618 thetamu=rmu.GetX(2,"sph","rad");
14619 gbin=hAeffProfile->FindFixBin(log10(E),cos(thetamu));
14620 if (gbin>0 && gbin<nbinsA+1)
14621 {
14622 Aeff=hAeffProfile->GetBinContent(gbin);
14623 if (Aeff>0)
14624 {
14625 Fluence=1./Aeff;
14626 fBurstOnAeff.Enter(Aeff,Fluence,E,dang);
14627 fBurstSigAeff.Enter(Aeff,Fluence,E,dang);
14628 }
14629 }
14630 }
14631 }
14632 } // End of loop over the signal events of this burst
14633
14634 if (fixedwinset) continue;
14635
14636 // Store the dynamic On-source and Off-source maximum (solid) angles that are encountered for this burst
14637 if (fDawin<0) // Local zenith band
14638 {
14639 thlow=thetagrb-0.5*dangmaxon;
14640 thup=thetagrb+0.5*dangmaxon;
14641 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14642 sx->SetSignal(dangmaxon,"dangmaxOn");
14643 sx->SetSignal(solidangle,"OmegaOn");
14644 thlow=thetagrb-0.5*dangmaxoff;
14645 thup=thetagrb+0.5*dangmaxoff;
14646 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14647 sx->SetSignal(dangmaxoff,"dangmaxOff");
14648 sx->SetSignal(solidangle*float(fNbkg),"OmegaOff");
14649 }
14650 else // Circle around GRB position
14651 {
14652 thlow=0;
14653 thup=dangmaxon;
14654 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14655 sx->SetSignal(solidangle,"OmegaOn");
14656 sx->SetSignal(dangmaxon,"dangmaxOn");
14657 thup=dangmaxoff;
14658 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
14659 sx->SetSignal(dangmaxoff,"dangmaxOff");
14660 sx->SetSignal(solidangle*float(fNbkg),"OmegaOff");
14661 }
14662 } // End of loop over the individual GRBs
14663
14664 // Remove the temporary storage of the background event
14665 if (fNgrbs>0) RemoveSignal(fNgrbs+1,0,0);
14666
14667 // Compensate statistical underfluctuation in number of GRB signal events if requested by fGrbnu<0
14668 if (fGrbnu<0 && fSigEmode=="SigE") BurstCompensate(nmugrb);
14669
14670 // Determine the On-source and Off-source total stacked solid angles that have been encountered
14671 name="SolidangleOn";
14672 fBurstParameters->AddNamedSlot(name);
14673 fBurstParameters->SetSignal(0,name);
14674 name="SolidangleOff";
14675 fBurstParameters->AddNamedSlot(name);
14676 fBurstParameters->SetSignal(0,name);
14677 for (Int_t igrb=1; igrb<=fNgrbs; igrb++)
14678 {
14679 sx=GetSignal(igrb);
14680
14681 if (!sx) continue;
14682
14683 solidangle=sx->GetSignal("OmegaOn");
14684 fBurstParameters->AddSignal(solidangle,"SolidangleOn");
14685 solidangle=sx->GetSignal("OmegaOff");
14686 fBurstParameters->AddSignal(solidangle,"SolidangleOff");
14687 }
14688
14689 // Determine and list the burst statistics
14690 MakeBurstDataStats(0,nmugrb);
14691}
14692
14693void NcAstrolab::MakeBurstDataStats(Int_t mode,Int_t nmugrb)
14694{
14709
14710 Double_t pi=acos(-1.);
14711
14712 // Retrieve the needed parameters
14713 Int_t fNgrbs=TMath::Nint(fBurstParameters->GetSignal("Ngrbs"));
14714 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
14715 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
14716 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
14717 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
14718 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
14719 Int_t fTbint90=TMath::Nint(fBurstParameters->GetSignal("Tbint90"));
14720 Float_t fTbin=fBurstParameters->GetSignal("Tbin");
14721 Float_t fVarTbin=fBurstParameters->GetSignal("VarTbin");
14722 Float_t fAbin=fBurstParameters->GetSignal("Abin");
14723 Float_t fAvgrbz=fBurstParameters->GetSignal("Avgrbz");
14724 Float_t fAvgrbt90=fBurstParameters->GetSignal("Avgrbt90");
14725 Float_t fRbkgDecl=fBurstParameters->GetSignal("RbkgDecl");
14726 Float_t fSolidangleOn=fBurstParameters->GetSignal("SolidangleOn");
14727 Float_t fSolidangleOff=fBurstParameters->GetSignal("SolidangleOff");
14728 Float_t fEnergyOn=fBurstParameters->GetSignal("EnergyOn");
14729 Float_t fEnergyOff=fBurstParameters->GetSignal("EnergyOff");
14730 Float_t fEnergySig=fBurstParameters->GetSignal("EnergySig");
14731 Float_t fEnergyBkg=fEnergyOn-fEnergySig;
14732 Float_t fSensarea=fBurstParameters->GetSignal("Sensarea");
14733
14734 TString tu="days";
14735 if (fTunits==1) tu="hours";
14736 if (fTunits==2) tu="sec";
14737 if (fTunits==3) tu="ns";
14738 if (fTunits==4) tu="ps";
14739
14740 Int_t non=fBurstOnMatch.GetN();
14741 Int_t noff=fBurstOffMatch.GetN();
14742 Int_t nsig=fBurstSignal.GetN();
14743 Double_t TminOn=fTmin;
14744 Double_t TmaxOn=fTmax;
14745 Double_t TminOff=fTmin;
14746 Double_t TmaxOff=fTmax;
14747
14748 if (fTmax<=fTmin)
14749 {
14750 TminOn=fBurstOnMatch.GetMinimum("dtime");
14751 TmaxOn=fBurstOnMatch.GetMaximum("dtime");
14752 TminOff=fBurstOffMatch.GetMinimum("dtime");
14753 TmaxOff=fBurstOffMatch.GetMaximum("dtime");
14754 }
14755
14756 Double_t AminOn=fBurstOnMatch.GetMinimum("dang");
14757 Double_t AmaxOn=fBurstOnMatch.GetMaximum("dang");
14758 Double_t AminOff=fBurstOffMatch.GetMinimum("dang");
14759 Double_t AmaxOff=fBurstOffMatch.GetMaximum("dang");
14760
14761 // Update the time window sizes and the average number of background events in them
14762 Float_t DtwinOn=TmaxOn-TminOn;
14763 Float_t DtwinOff=TmaxOff-TminOff;
14764 Float_t NbkgWinOn=fRbkgDecl*DtwinOn*fTfact;
14765 Float_t NbkgWinOff=fRbkgDecl*DtwinOff*fTfact;
14766
14767 TString title;
14768 TString name;
14769 TString s;
14770 Float_t xmin=0;
14771 Float_t xmax=0;
14772 TAxis* axis=0;
14773 Int_t nbins=0;
14774 Double_t binsize=0;
14775 Double_t binsizecos=0;
14776 Int_t nabinsOn=0;
14777 Double_t abinsizeOn=0;
14778 Int_t nabinsOff=0;
14779 Double_t abinsizeOff=0;
14780
14781 // The source redshift, position and reconstruction uncertainty histograms
14782 TH1F* hOnSourceZ=0;
14783 TH1F* hOffSourceZ=0;
14784 TH1F* hOnSigSourceZ=0;
14785 TH1F* hOnSigmaSource=0;
14786 TH1F* hOffSigmaSource=0;
14787 TH1F* hOnSigSigmaSource=0;
14788 TH1F* hOnSigmaReco=0;
14789 TH1F* hOffSigmaReco=0;
14790 TH1F* hOnSigSigmaReco=0;
14791 TH1F* hOnSigmaComb=0;
14792 TH1F* hOffSigmaComb=0;
14793 TH1F* hOnSigSigmaComb=0;
14794 nbins=100;
14795 if (fBurstOnReco.GetN())
14796 {
14797 title.Form("On-Source object redshifts with matching event(s);Redshift;Counts");
14798 hOnSourceZ=new TH1F("hOnSourceZ",title,nbins,1,0);
14799 hOnSourceZ->SetBuffer(non);
14800
14801 title.Form("On-Source object position uncertainties with matching event(s);Object position angular uncertainty (sigma in degrees);Counts");
14802 hOnSigmaSource=new TH1F("hOnSigmaSource",title,nbins,1,0);
14803 hOnSigmaSource->SetBuffer(non);
14804
14805 title.Form("On-source event reconstruction uncertainties in the final sample;Event angular reconstruction uncertainty (sigma in degrees);Counts");
14806 hOnSigmaReco=new TH1F("hOnSigmaReco",title,nbins,1,0);
14807 hOnSigmaReco->SetBuffer(non);
14808
14809 title.Form("On-source combined object position and event reconstruction uncertainty;Combined object position and event reco angular uncertainty (sigma in degrees);Counts");
14810 hOnSigmaComb=new TH1F("hOnSigmaComb",title,nbins,1,0);
14811 hOnSigmaComb->SetBuffer(non);
14812 }
14813
14814 if (fBurstOffReco.GetN())
14815 {
14816 title.Form("Off-Source object redshifts with matching event(s);Redshift;Counts");
14817 hOffSourceZ=new TH1F("hOffSourceZ",title,nbins,1,0);
14818 hOffSourceZ->SetBuffer(noff);
14819
14820 title.Form("Off-Source object position uncertainties with matching event(s);Object position angular uncertainty (sigma in degrees);Counts");
14821 hOffSigmaSource=new TH1F("hOffSigmaSource",title,nbins,1,0);
14822 hOffSigmaSource->SetBuffer(noff);
14823
14824 title.Form("Off-source event reconstruction uncertainties in the final sample;Event angular reconstruction uncertainty (sigma in degrees);Counts");
14825 hOffSigmaReco=new TH1F("hOffSigmaReco",title,nbins,1,0);
14826 hOffSigmaReco->SetBuffer(noff);
14827
14828 title.Form("Off-source combined object position and event reconstruction uncertainty;Combined object position and event reco angular uncertainty (sigma in degrees);Counts");
14829 hOffSigmaComb=new TH1F("hOffSigmaComb",title,nbins,1,0);
14830 hOffSigmaComb->SetBuffer(noff);
14831 }
14832
14833 if (fBurstSigReco.GetN())
14834 {
14835 title.Form("On-Source object redshifts with matching simulated signal event(s);Redshift;Counts");
14836 hOnSigSourceZ=new TH1F("hOnSigSourceZ",title,nbins,1,0);
14837 hOnSigSourceZ->SetBuffer(nsig);
14838
14839 title.Form("On-Source object position uncertainties with matching simulated signal event(s);Object position angular uncertainty (sigma in degrees);Counts");
14840 hOnSigSigmaSource=new TH1F("hOnSigSigmaSource",title,nbins,1,0);
14841 hOnSigSigmaSource->SetBuffer(nsig);
14842
14843 title.Form("On-source simulated signal event reconstruction uncertainties in the final sample;Event angular reconstruction uncertainty (sigma in degrees);Counts");
14844 hOnSigSigmaReco=new TH1F("hOnSigSigmaReco",title,nbins,1,0);
14845 hOnSigSigmaReco->SetBuffer(nsig);
14846
14847 title.Form("On-source combined object position and simulated signal event reconstruction uncertainty;Combined object position and event reco angular uncertainty (sigma in degrees);Counts");
14848 hOnSigSigmaComb=new TH1F("hOnSigSigmaComb",title,nbins,1,0);
14849 hOnSigSigmaComb->SetBuffer(nsig);
14850 }
14851
14852 // The energy histograms
14853 TH1F* hOnE=0;
14854 TH1F* hOffE=0;
14855 TH1F* hOnSigE=0;
14856 nbins=1000;
14857 if (non)
14858 {
14859 title.Form("On-source reconstructed event energy in the final sample;Event energy in GeV;Counts");
14860 if (!mode) title.ReplaceAll("reconstructed","simulated");
14861 hOnE=new TH1F("hOnE",title,nbins,1,0);
14862 }
14863 if (noff)
14864 {
14865 title.Form("Off-source reconstructed event energy in the final sample;Event energy in GeV;Counts");
14866 if (!mode) title.ReplaceAll("reconstructed","simulated");
14867 hOffE=new TH1F("hOffE",title,nbins,1,0);
14868 }
14869 if (nsig)
14870 {
14871 title.Form("On-source simulated signal event energy in the final sample;Event energy in GeV;Counts");
14872 hOnSigE=new TH1F("hOnSigE",title,nbins,1,0);
14873 }
14874
14875 // Additional text for histo titles to indicate scrambling of the corresponding data
14876 TString scrt=""; // Time scrambling
14877 TString scrp=""; // Position scrambling
14878 if (fTscmode>0) scrt="(scrambled)";
14879 if (fRscmode>0 || fTscmode==3) scrp="(scrambled)";
14880
14881 // Create the angular separation histograms
14882 TH1F* hOna=0;
14883 TH1F* hOffa=0;
14884 TH1F* hOnSiga=0;
14885 TH1F* hOnCosa=0;
14886 TH1F* hOffCosa=0;
14887 TH1F* hOnSigcosa=0;
14888 if (non && fAbin)
14889 {
14890 if (fAbin>0)
14891 {
14892 binsize=fAbin;
14893 nbins=int((AmaxOn-AminOn)/binsize);
14894 }
14895 else
14896 {
14897 nbins=int(((AmaxOn-AminOn)/180.)*NbkgWinOn*float(fNgrbs)/fabs(fAbin));
14898 if (nbins) binsize=(AmaxOn-AminOn)/float(nbins);
14899 }
14900 if (nbins)
14901 {
14902 title.Form("Reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Counts per %-.3g degrees",scrp.Data(),binsize);
14903 hOna=new TH1F("hOna",title,nbins+1,AminOn,AmaxOn+binsize);
14904 }
14905 else
14906 {
14907 nbins=100;
14908 binsize=AmaxOn/float(nbins);
14909 title.Form("Reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Counts per %-.3g degrees",scrp.Data(),binsize);
14910 hOna=new TH1F("hOna",title,nbins+2,AminOn-binsize,AmaxOn+binsize);
14911 }
14912 nabinsOn=nbins;
14913 abinsizeOn=binsize;
14914 if (nbins) binsizecos=(cos(AminOn*pi/180.)-cos(AmaxOn*pi/180.))/float(nbins);
14915 if (binsizecos>0)
14916 {
14917 title.Form("Reconstructed %-s cos(opening angle) of on-source events in time window;cos(opening angle);Counts per %-.3g",scrp.Data(),binsizecos);
14918 hOnCosa=new TH1F("hOnCosa",title,nbins+1,cos(AmaxOn*pi/180.),cos(AminOn*pi/180.)+binsizecos);
14919 }
14920 else
14921 {
14922 nbins=100;
14923 binsizecos=fabs(cos(AmaxOn*pi/180.))/float(nbins);
14924 title.Form("Reconstructed %-s cos(opening angle) of on-source events in time window;cos(opening angle);Counts per %-.3g",scrp.Data(),binsizecos);
14925 hOnCosa=new TH1F("hOnCosa",title,nbins+2,cos(AmaxOn*pi/180.)-binsizecos,cos(AminOn*pi/180.)+binsizecos);
14926 }
14927 }
14928 if (nsig && nbins)
14929 {
14930 title.Form("Reconstructed opening angle of on-source simulated signal events in time window;Opening angle (degrees);Counts per %-.3g degrees",binsize);
14931 hOnSiga=new TH1F("hOnSiga",title,nbins+2,AminOn-binsize,AmaxOn+binsize);
14932 title.Form("Reconstructed cos(opening angle) of on-source simulated signal events in time window;cos(opening angle);Counts per %-.3g",binsizecos);
14933 hOnSigcosa=new TH1F("hOnSigcosa",title,nbins+2,cos(AmaxOn*pi/180.)-binsizecos,cos(AminOn*pi/180.)+binsizecos);
14934 }
14935 nbins=0;
14936 binsize=0;
14937 binsizecos=0;
14938 if (noff && fAbin)
14939 {
14940 if (fAbin>0)
14941 {
14942 binsize=fAbin;
14943 nbins=int((AmaxOff-AminOff)/binsize);
14944 }
14945 else
14946 {
14947 nbins=int(((AmaxOff-AminOff)/180.)*NbkgWinOff*float(fNgrbs)*float(fNbkg)/fabs(fAbin));
14948 if (nbins) binsize=(AmaxOff-AminOff)/float(nbins);
14949 }
14950 if (nbins)
14951 {
14952 title.Form("Reconstructed opening angle of off-source events in time window;Opening angle (degrees);Counts per %-.3g degrees",binsize);
14953 hOffa=new TH1F("hOffa",title,nbins+1,AminOff,AmaxOff+binsize);
14954 }
14955 else
14956 {
14957 nbins=100;
14958 binsize=AmaxOff/float(nbins);
14959 title.Form("Reconstructed opening angle of off-source events in time window;Opening angle (degrees);Counts per %-.3g degrees",binsize);
14960 hOffa=new TH1F("hOffa",title,nbins+2,AminOff-binsize,AmaxOff+binsize);
14961 }
14962 nabinsOff=nbins;
14963 abinsizeOff=binsize;
14964 if (nbins) binsizecos=(cos(AminOff*pi/180.)-cos(AmaxOff*pi/180.))/float(nbins);
14965 if (binsizecos>0)
14966 {
14967 title.Form("Reconstructed cos(opening angle) of off-source events in time window;cos(opening angle);Counts per %-.3g",binsizecos);
14968 hOffCosa=new TH1F("hOffCosa",title,nbins+1,cos(AmaxOff*pi/180.),cos(AminOff*pi/180.)+binsizecos);
14969 }
14970 else
14971 {
14972 nbins=100;
14973 binsizecos=fabs(cos(AmaxOff*pi/180.))/float(nbins);
14974 title.Form("Reconstructed cos(opening angle) of off-source events in time window;cos(opening angle);Counts per %-.3g",binsizecos);
14975 hOffCosa=new TH1F("hOffCosa",title,nbins+2,cos(AmaxOff*pi/180.)-binsizecos,cos(AminOff*pi/180.)+binsizecos);
14976 }
14977 }
14978
14979 // Create the arrival time histograms
14980 TH1F* hOnt=0;
14981 TH1F* hOfft=0;
14982 TH1F* hOnSigt=0;
14983 TH2F* hOnta=0;
14984 TH2F* hOffta=0;
14985 TH2F* hOnSigta=0;
14986 TH2F* hOnZta=0;
14987 TH2F* hOffZta=0;
14988 TH2F* hOnSigZta=0;
14989
14990 // The redshift corrected arrival time histograms
14991 TH1F* hOnZt=0;
14992 TH1F* hOffZt=0;
14993 TH1F* hOnSigZt=0;
14994
14995 nbins=0;
14996 binsize=0;
14997 TString addtitle;
14998 addtitle.Form(" (=%-g*<T90>)",fTbin);
14999 if (fTbin<0) addtitle.Form(" (~%-g counts/bin)",fabs(fTbin));
15000 if (fabs(fTbin)>0) // Fixed time bins
15001 {
15002 // Automatic time binning to get the specified maximal bkg counts per bin
15003 nbins=int(NbkgWinOn*float(fNgrbs)/fabs(fTbin));
15004 Int_t temp=int(NbkgWinOff*float(fNgrbs)*float(fNbkg)/fabs(fTbin));
15005 if (temp>nbins) nbins=temp;
15006 if (nbins) binsize=DtwinOn/float(nbins);
15007
15008 if (fTbin>0) // User defined time bin size
15009 {
15010 binsize=fTbin;
15011 if (fTbint90) binsize=fTbin*fabs(fAvgrbt90)/fTfact;
15012 nbins=DtwinOn/binsize;
15013 }
15014 if (nbins && non)
15015 {
15016 title.Form("Arrival times %-s of on-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",scrt.Data(),tu.Data(),binsize,tu.Data());
15017 if (fTbint90 || fTbin<0) title+=addtitle;
15018 hOnt=new TH1F("hOnt",title,nbins+2,TminOn-binsize,TmaxOn+binsize);
15019 title.Form("Arrival time %-s vs. reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",scrt.Data(),scrp.Data(),tu.Data());
15020 hOnta=new TH2F("hOnta",title,nabinsOn+2,AminOn-abinsizeOn,AmaxOn+abinsizeOn,nbins+2,TminOn-binsize,TmaxOn+binsize);
15021 title.Form("Redshift corrected arrival times %-s of on-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",scrt.Data(),tu.Data(),binsize,tu.Data());
15022 if (fTbint90 || fTbin<0) title+=addtitle;
15023 hOnZt=new TH1F("hOnZt",title,nbins+2,TminOn-binsize,TmaxOn+binsize);
15024 title.Form("Redshift corrected %-s arrival time vs. reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",scrt.Data(),scrp.Data(),tu.Data());
15025 hOnZta=new TH2F("hOnZta",title,nabinsOn+2,AminOn-abinsizeOn,AmaxOn+abinsizeOn,nbins+2,TminOn-binsize,TmaxOn+binsize);
15026 }
15027 if (nbins && nsig)
15028 {
15029 title.Form("Arrival times of on-source simulated signal events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",tu.Data(),binsize,tu.Data());
15030 if (fTbint90 || fTbin<0) title+=addtitle;
15031 hOnSigt=new TH1F("hOnSigt",title,nbins+2,TminOn-binsize,TmaxOn+binsize);
15032 title.Form("Arrival time vs. reconstructed opening angle of on-source simulated signal events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15033 hOnSigta=new TH2F("hOnSigta",title,nabinsOn+2,AminOn-abinsizeOn,AmaxOn+abinsizeOn,nbins+2,TminOn-binsize,TmaxOn+binsize);
15034 title.Form("Redshift corrected arrival times of on-source simulated signal events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",tu.Data(),binsize,tu.Data());
15035 if (fTbint90 || fTbin<0) title+=addtitle;
15036 hOnSigZt=new TH1F("hOnSigZt",title,nbins+2,TminOn-binsize,TmaxOn+binsize);
15037 title.Form("Redshift corrected arrival time vs. reconstructed opening angle of on-source simulated signal events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15038 hOnSigZta=new TH2F("hOnSigZta",title,nabinsOn+2,AminOn-abinsizeOn,AmaxOn+abinsizeOn,nbins+2,TminOn-binsize,TmaxOn+binsize);
15039 }
15040
15041 if (fTbin>0) // User defined time bin size
15042 {
15043 binsize=fTbin;
15044 if (fTbint90) binsize=fTbin*fabs(fAvgrbt90)/fTfact;
15045 nbins=DtwinOff/binsize;
15046 }
15047 if (nbins && noff)
15048 {
15049 title.Form("Arrival times of off-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",tu.Data(),binsize,tu.Data());
15050 if (fTbint90 || fTbin<0) title+=addtitle;
15051 hOfft=new TH1F("hOfft",title,nbins+2,TminOff-binsize,TmaxOff+binsize);
15052 title.Form("Arrival time vs. reconstructed opening angle of off-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15053 hOffta=new TH2F("hOffta",title,nabinsOff+2,AminOff-abinsizeOff,AmaxOff+abinsizeOff,nbins+2,TminOff-binsize,TmaxOff+binsize);
15054 title.Form("Redshift corrected arrival times of off-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per %-.3g %-s",tu.Data(),binsize,tu.Data());
15055 if (fTbint90 || fTbin<0) title+=addtitle;
15056 hOffZt=new TH1F("hOffZt",title,nbins+2,TminOff-binsize,TmaxOff+binsize);
15057 title.Form("Redshift corrected arrival time vs. reconstructed opening angle of off-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15058 hOffZta=new TH2F("hOffZta",title,nabinsOff+2,AminOff-abinsizeOff,AmaxOff+abinsizeOff,nbins+2,TminOff-binsize,TmaxOff+binsize);
15059 }
15060 }
15061 else // Variable time bins
15062 {
15063 Double_t* binarr=0;
15064 Int_t nbx=int(DtwinOn/fVarTbin);
15065 Float_t gamma=fabs(fAvgrbz)+1.;
15066 Float_t* bins=new Float_t[nbx];
15067 nbins=0;
15068 Float_t xlow=0,xup=0,size=fVarTbin;
15069 for (Int_t i=0; i<nbx-1; i++)
15070 {
15071 xup=xlow+size;
15072 if (xup>DtwinOn/2.) // Store the last lowerbound
15073 {
15074 bins[i]=xlow;
15075 nbins++;
15076 break;
15077 }
15078 bins[i]=xlow;
15079 nbins++;
15080 xlow=xup;
15081 size=xlow*gamma;
15082 }
15083 binarr=new Double_t[2*nbins-1];
15084 for (Int_t j=nbins; j>0; j--)
15085 {
15086 binarr[nbins-j]=-bins[j-1];
15087 binarr[nbins+j-2]=bins[j-1];
15088 }
15089 nbins=2*nbins-2;
15090 if (nbins && non)
15091 {
15092 title.Form("Arrival times %-s of on-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per time bin",scrt.Data(),tu.Data());
15093 hOnt=new TH1F("hOnt",title,nbins,binarr);
15094 if (nabinsOn)
15095 {
15096 title.Form("Arrival time %-s vs. reconstructed %-s opening angle of on-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",scrt.Data(),scrp.Data(),tu.Data());
15097 hOnta=new TH2F("hOnta",title,nabinsOn,AminOn,AmaxOn,nbins,binarr);
15098 }
15099 }
15100 if (nbins && noff)
15101 {
15102 title.Form("Arrival times of off-source events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per time bin",tu.Data());
15103 hOfft=new TH1F("hOfft",title,nbins,binarr);
15104 if (nabinsOff)
15105 {
15106 title.Form("Arrival time vs. reconstructed opening angle of off-source events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15107 hOffta=new TH2F("hOffta",title,nabinsOff,AminOff,AmaxOff,nbins,binarr);
15108 }
15109 }
15110 if (nbins && nsig)
15111 {
15112 title.Form("Arrival times of on-source simulated signal events in time window;Event arrival time (in %-s) w.r.t. burst trigger;Counts per time bin",tu.Data());
15113 hOnSigt=new TH1F("hOnSigt",title,nbins,binarr);
15114 if (nabinsOn)
15115 {
15116 title.Form("Arrival time vs. reconstructed opening angle of on-source simulated signal events in time window;Opening angle (degrees);Event arrival time (in %-s) w.r.t. burst trigger",tu.Data());
15117 hOnSigta=new TH2F("hOnSigta",title,nabinsOn,AminOn,AmaxOn,nbins,binarr);
15118 }
15119 }
15120
15121 delete[] binarr;
15122 }
15123
15124 // Fill the histograms
15125 Double_t value1=0;
15126 Double_t value2=0;
15127 Double_t value3=0;
15128 Double_t value4=0;
15129
15130 // The on-source data
15131 for (Int_t i=1; i<=fBurstOnReco.GetN(); i++)
15132 {
15133 value1=fBurstOnReco.GetEntry(i,"zburst");
15134 value2=fBurstOnReco.GetEntry(i,"sigmaburst");
15135 value3=fBurstOnReco.GetEntry(i,"sigmareco");
15136 value4=fBurstOnReco.GetEntry(i,"sigmacomb");
15137 if (hOnSourceZ) hOnSourceZ->Fill(value1);
15138 if (hOnSigmaSource) hOnSigmaSource->Fill(value2);
15139 if (hOnSigmaReco) hOnSigmaReco->Fill(value3);
15140 if (hOnSigmaComb) hOnSigmaComb->Fill(value4);
15141 }
15142
15143 for (Int_t i=1; i<=fBurstOnMatch.GetN(); i++)
15144 {
15145 value1=fBurstOnMatch.GetEntry(i,"E");
15146 value2=fBurstOnMatch.GetEntry(i,"dang");
15147 value3=fBurstOnMatch.GetEntry(i,"dtime");
15148 value4=fBurstOnMatch.GetEntry(i,"dtimez");
15149 if (hOnE) hOnE->Fill(value1);
15150 if (hOna) hOna->Fill(value2);
15151 if (hOnCosa) hOnCosa->Fill(cos(value2*pi/180.));
15152 if (hOnt) hOnt->Fill(value3);
15153 if (hOnta) hOnta->Fill(value2,value3);
15154 if (hOnZt) hOnZt->Fill(value4);
15155 if (hOnZta) hOnZta->Fill(value2,value4);
15156 }
15157
15158 // The off-source data
15159 for (Int_t i=1; i<=fBurstOffReco.GetN(); i++)
15160 {
15161 value1=fBurstOffReco.GetEntry(i,"zburst");
15162 value2=fBurstOffReco.GetEntry(i,"sigmaburst");
15163 value3=fBurstOffReco.GetEntry(i,"sigmareco");
15164 value4=fBurstOffReco.GetEntry(i,"sigmacomb");
15165 if (hOffSourceZ) hOffSourceZ->Fill(value1);
15166 if (hOffSigmaSource) hOffSigmaSource->Fill(value2);
15167 if (hOffSigmaReco) hOffSigmaReco->Fill(value3);
15168 if (hOffSigmaComb) hOffSigmaComb->Fill(value4);
15169 }
15170
15171 for (Int_t i=1; i<=fBurstOffMatch.GetN(); i++)
15172 {
15173 value1=fBurstOffMatch.GetEntry(i,"E");
15174 value2=fBurstOffMatch.GetEntry(i,"dang");
15175 value3=fBurstOffMatch.GetEntry(i,"dtime");
15176 value4=fBurstOffMatch.GetEntry(i,"dtimez");
15177 if (hOffE) hOffE->Fill(value1);
15178 if (hOffa) hOffa->Fill(value2);
15179 if (hOffCosa) hOffCosa->Fill(cos(value2*pi/180.));
15180 if (hOfft) hOfft->Fill(value3);
15181 if (hOffta) hOffta->Fill(value2,value3);
15182 if (hOffZt) hOffZt->Fill(value4);
15183 if (hOffZta) hOffZta->Fill(value2,value4);
15184 }
15185
15186 // The simulated signal data
15187 for (Int_t i=1; i<=fBurstSigReco.GetN(); i++)
15188 {
15189 value1=fBurstSigReco.GetEntry(i,"zburst");
15190 value2=fBurstSigReco.GetEntry(i,"sigmaburst");
15191 value3=fBurstSigReco.GetEntry(i,"sigmareco");
15192 value4=fBurstSigReco.GetEntry(i,"sigmacomb");
15193 if (hOnSigSourceZ) hOnSigSourceZ->Fill(value1);
15194 if (hOnSigSigmaSource) hOnSigSigmaSource->Fill(value2);
15195 if (hOnSigSigmaReco) hOnSigSigmaReco->Fill(value3);
15196 if (hOnSigSigmaComb) hOnSigSigmaComb->Fill(value4);
15197 }
15198
15199 for (Int_t i=1; i<=fBurstSignal.GetN(); i++)
15200 {
15201 value1=fBurstSignal.GetEntry(i,"E");
15202 value2=fBurstSignal.GetEntry(i,"dang");
15203 value3=fBurstSignal.GetEntry(i,"dtime");
15204 value4=fBurstSignal.GetEntry(i,"dtimez");
15205 if (hOnSigE) hOnSigE->Fill(value1);
15206 if (hOnSiga) hOnSiga->Fill(value2);
15207 if (hOnSigcosa) hOnSigcosa->Fill(cos(value2*pi/180.));
15208 if (hOnSigt) hOnSigt->Fill(value3);
15209 if (hOnSigta) hOnSigta->Fill(value2,value3);
15210 if (hOnSigZt) hOnSigZt->Fill(value4);
15211 if (hOnSigZta) hOnSigZta->Fill(value2,value4);
15212 }
15213
15214 // Bayesian block analysis of the arrival times
15215 NcBlocks BB;
15216 TH1F hOnBBt;
15217 TH1F hOnBBzt;
15218 if (fBurstOnMatch.GetN())
15219 {
15220 BB.GetBlocks(fBurstOnMatch,"dtime",0.05,&hOnBBt);
15221 title.Form("Bayesian blocks for on-source arrival times %-s;Event arrival time (in %-s) w.r.t. burst trigger;Event rate (%-s^{-1}) for %-i stacked time windows",scrt.Data(),tu.Data(),tu.Data(),fNgrbs);
15222 title.ReplaceAll("days^","day^");
15223 title.ReplaceAll("hours^","hour^");
15224 hOnBBt.SetNameTitle("hOnBBt",title);
15225 BB.GetBlocks(fBurstOnMatch,"dtimez",0.05,&hOnBBzt);
15226 title.Form("Bayesian blocks for redshift corrected on-source arrival times %-s;Event arrival time (in %-s) w.r.t. burst trigger;Event rate (%-s^{-1}) for %-i stacked time windows",scrt.Data(),tu.Data(),tu.Data(),fNgrbs);
15227 title.ReplaceAll("days^","day^");
15228 title.ReplaceAll("hours^","hour^");
15229 hOnBBzt.SetNameTitle("hOnBBzt",title);
15230 }
15231 TH1F hOffBBt;
15232 TH1F hOffBBzt;
15233 if (fBurstOffMatch.GetN())
15234 {
15235 BB.GetBlocks(fBurstOffMatch,"dtime",0.05,&hOffBBt);
15236 title.Form("Bayesian blocks for off-source arrival times;Event arrival time (in %-s) w.r.t. burst trigger;Event rate (%-s^{-1}) for %-i stacked time windows",tu.Data(),tu.Data(),fNgrbs*fNbkg);
15237 title.ReplaceAll("days^","day^");
15238 title.ReplaceAll("hours^","hour^");
15239 hOffBBt.SetNameTitle("hOffBBt",title);
15240 BB.GetBlocks(fBurstOffMatch,"dtimez",0.05,&hOffBBzt);
15241 title.Form("Bayesian blocks for redshift corrected off-source arrival times;Event arrival time (in %-s) w.r.t. burst trigger;Event rate (%-s^{-1}) for %-i stacked time windows",tu.Data(),tu.Data(),fNgrbs*fNbkg);
15242 title.ReplaceAll("days^","day^");
15243 title.ReplaceAll("hours^","hour^");
15244 hOffBBzt.SetNameTitle("hOffBBzt",title);
15245 }
15246
15247 // Ratio On/Off for the Bayesian Block histograms
15248 Float_t temp=0;
15249 Int_t nb1=0;
15250 Int_t nb2=0;
15251
15252 axis=hOnBBt.GetXaxis();
15253 xmin=axis->GetXmin();
15254 xmax=axis->GetXmax();
15255 axis=hOffBBt.GetXaxis();
15256 temp=axis->GetXmin();
15257 if (temp<xmin) xmin=temp;
15258 temp=axis->GetXmax();
15259 if (temp>xmax) xmax=temp;
15260
15261 TH1F hOnUBBt;
15262 TH1F hOffUBBt;
15263 TH1F hRatUBBt;
15264 title.Form("Event rate (%-s^{-1}) scaled per time window",tu.Data());
15265 title.ReplaceAll("days^","day^");
15266 title.ReplaceAll("hours^","hour^");
15267 nb1=BB.Rebin(&hOnBBt,&hOnUBBt,kFALSE,0,xmin,xmax);
15268 nb2=BB.Rebin(&hOffBBt,&hOffUBBt,kFALSE,0,xmin,xmax);
15269 if (nb2>nb1) BB.Rebin(&hOnBBt,&hOnUBBt,kFALSE,nb2,xmin,xmax);
15270 hOnUBBt.SetName("hOnUBBt");
15271 hOffUBBt.SetName("hOffUBBt");
15272 if (fNgrbs>1) hOnUBBt.Scale(1./float(fNgrbs));
15273 if (fNgrbs*fNbkg>1) hOffUBBt.Scale(1./float(fNgrbs*fNbkg));
15274 hOnUBBt.SetYTitle(title);
15275 hOffUBBt.SetYTitle(title);
15276 BB.Divide(&hOnUBBt,&hOffUBBt,&hRatUBBt,kFALSE,1);
15277 hRatUBBt.SetName("hRatUBBt");
15278 hRatUBBt.SetYTitle("Ratio");
15279
15280 nbins=hOnBBzt.GetNbinsX();
15281 if (hOffBBzt.GetNbinsX()>nbins) nbins=hOffBBzt.GetNbinsX();
15282 axis=hOnBBzt.GetXaxis();
15283 xmin=axis->GetXmin();
15284 xmax=axis->GetXmax();
15285 axis=hOffBBzt.GetXaxis();
15286 temp=axis->GetXmin();
15287 if (temp<xmin) xmin=temp;
15288 temp=axis->GetXmax();
15289 if (temp>xmax) xmax=temp;
15290
15291 TH1F hOnUBBzt;
15292 TH1F hOffUBBzt;
15293 TH1F hRatUBBzt;
15294 nb1=BB.Rebin(&hOnBBzt,&hOnUBBzt,kFALSE,0,xmin,xmax);
15295 nb2=BB.Rebin(&hOffBBzt,&hOffUBBzt,kFALSE,0,xmin,xmax);
15296 if (nb2>nb1) BB.Rebin(&hOnBBzt,&hOnUBBzt,kFALSE,nb2,xmin,xmax);
15297 hOnUBBzt.SetName("hOnUBBzt");
15298 hOffUBBzt.SetName("hOffUBBzt");
15299 if (fNgrbs>1) hOnUBBzt.Scale(1./float(fNgrbs));
15300 if (fNgrbs*fNbkg>1) hOffUBBzt.Scale(1./float(fNgrbs*fNbkg));
15301 hOnUBBzt.SetYTitle(title);
15302 hOffUBBzt.SetYTitle(title);
15303 BB.Divide(&hOnUBBzt,&hOffUBBzt,&hRatUBBzt,kFALSE,1);
15304 hRatUBBzt.SetName("hRatUBBzt");
15305 hRatUBBzt.SetYTitle("Ratio");
15306
15307 // Store the produced histograms
15308 if (hOnSourceZ) fBurstHistos.Add(hOnSourceZ);
15309 if (hOffSourceZ) fBurstHistos.Add(hOffSourceZ);
15310 if (hOnSigSourceZ) fBurstHistos.Add(hOnSigSourceZ);
15311 if (hOnSigmaSource) fBurstHistos.Add(hOnSigmaSource);
15312 if (hOffSigmaSource) fBurstHistos.Add(hOffSigmaSource);
15313 if (hOnSigSigmaSource) fBurstHistos.Add(hOnSigSigmaSource);
15314 if (hOnSigmaReco) fBurstHistos.Add(hOnSigmaReco);
15315 if (hOffSigmaReco) fBurstHistos.Add(hOffSigmaReco);
15316 if (hOnSigSigmaReco) fBurstHistos.Add(hOnSigSigmaReco);
15317 if (hOnSigmaComb) fBurstHistos.Add(hOnSigmaComb);
15318 if (hOffSigmaComb) fBurstHistos.Add(hOffSigmaComb);
15319 if (hOnSigSigmaComb) fBurstHistos.Add(hOnSigSigmaComb);
15320 if (hOnE) fBurstHistos.Add(hOnE);
15321 if (hOffE) fBurstHistos.Add(hOffE);
15322 if (hOnSigE) fBurstHistos.Add(hOnSigE);
15323 if (hOna) fBurstHistos.Add(hOna);
15324 if (hOffa) fBurstHistos.Add(hOffa);
15325 if (hOnSiga) fBurstHistos.Add(hOnSiga);
15326 if (hOnCosa) fBurstHistos.Add(hOnCosa);
15327 if (hOffCosa) fBurstHistos.Add(hOffCosa);
15328 if (hOnSigcosa) fBurstHistos.Add(hOnSigcosa);
15329 if (hOnt) fBurstHistos.Add(hOnt);
15330 if (hOfft) fBurstHistos.Add(hOfft);
15331 if (hOnSigt) fBurstHistos.Add(hOnSigt);
15332 if (hOnta) fBurstHistos.Add(hOnta);
15333 if (hOffta) fBurstHistos.Add(hOffta);
15334 if (hOnSigta)fBurstHistos.Add(hOnSigta);
15335 if (hOnt && hOnBBt.GetEntries()) fBurstHistos.Add(hOnBBt.Clone());
15336 if (hOfft && hOffBBt.GetEntries()) fBurstHistos.Add(hOffBBt.Clone());
15337 if (hOnt && hOnUBBt.GetEntries()) fBurstHistos.Add(hOnUBBt.Clone());
15338 if (hOfft && hOffUBBt.GetEntries()) fBurstHistos.Add(hOffUBBt.Clone());
15339 if (hOnt && hOfft && hRatUBBt.GetEntries()) fBurstHistos.Add(hRatUBBt.Clone());
15340 if (hOnZt) fBurstHistos.Add(hOnZt);
15341 if (hOffZt) fBurstHistos.Add(hOffZt);
15342 if (hOnSigZt) fBurstHistos.Add(hOnSigZt);
15343 if (hOnZta) fBurstHistos.Add(hOnZta);
15344 if (hOffZta) fBurstHistos.Add(hOffZta);
15345 if (hOnSigZta) fBurstHistos.Add(hOnSigZta);
15346 if (hOnZt && hOnBBzt.GetEntries()) fBurstHistos.Add(hOnBBzt.Clone());
15347 if (hOffZt && hOffBBzt.GetEntries()) fBurstHistos.Add(hOffBBzt.Clone());
15348 if (hOnZt && hOnUBBzt.GetEntries()) fBurstHistos.Add(hOnUBBzt.Clone());
15349 if (hOffZt && hOffUBBzt.GetEntries()) fBurstHistos.Add(hOffUBBzt.Clone());
15350 if (hOnZt && hOffZt && hRatUBBzt.GetEntries()) fBurstHistos.Add(hRatUBBzt.Clone());
15351
15352 // Make sure that also the auto-binned histograms have their axes ranges set
15353 Int_t nh=fBurstHistos.GetEntries();
15354 for (Int_t ih=0; ih<nh; ih++)
15355 {
15356 TH1* hx=(TH1*)fBurstHistos.At(ih);
15357 if (!hx) continue;
15358 hx->BufferEmpty(1);
15359
15360 name=hx->GetName();
15361
15362 if (name=="hTdiff")
15363 {
15364 binsize=hx->GetBinWidth(1);
15365 s.Form("Counts per %-.3g %-s",binsize,tu.Data());
15366 axis=hx->GetYaxis();
15367 if (axis) axis->SetTitle(s);
15368 }
15369
15370 if (name=="hAdiff" || name.Contains("Sigma"))
15371 {
15372 binsize=hx->GetBinWidth(1);
15373 s.Form("Counts per %-.3g degrees",binsize);
15374 axis=hx->GetYaxis();
15375 if (axis) axis->SetTitle(s);
15376 }
15377
15378 if (name=="hOnE" || name=="hOffE" || name=="hOnSigE")
15379 {
15380 binsize=hx->GetBinWidth(1);
15381 s.Form("Counts per %-.3g GeV",binsize);
15382 axis=hx->GetYaxis();
15383 if (axis) axis->SetTitle(s);
15384 }
15385 }
15386
15387 // Determination of the on-source and off-source event rates
15388 Float_t nOn=non;
15389 Float_t nOff=noff;
15390 Float_t nsigOn=nsig;
15391 Float_t nbkgOn=nOn-nsigOn;
15392 Float_t Ton=DtwinOn*fTfact*float(fNgrbs); // Total on-source exposure time in seconds
15393 Float_t Toff=DtwinOff*fTfact*float(fNgrbs)*float(fNbkg); // Total off-source exposure time in seconds
15394 Float_t rateOn=nOn/(DtwinOn*fTfact);
15395 Float_t rateOff=nOff/(DtwinOff*fTfact);
15396
15397 // (Average) values per patch
15398 Float_t TwinOn=DtwinOn*fTfact;
15399 Float_t TwinOff=DtwinOff*fTfact;
15400 Float_t AvSolidangleOn=0;
15401 Float_t AvSolidangleOff=0;
15402 Float_t AvNon=0;
15403 Float_t AvNoff=0;
15404 Float_t AvRon=0;
15405 Float_t AvRoff=0;
15406 Float_t AvEon=0;
15407 Float_t AvEoff=0;
15408 Float_t AvNsigOn=0;
15409 Float_t AvNbkgOn=0;
15410 Float_t AvRsigOn=0;
15411 Float_t AvRbkgOn=0;
15412 Float_t AvEsigOn=0;
15413 Float_t AvEbkgOn=0;
15414 Float_t scale=fNgrbs;
15415 if (scale)
15416 {
15417 AvSolidangleOn=fSolidangleOn/scale;
15418 AvNon=nOn/scale;
15419 AvRon=nOn/Ton;
15420 AvEon=fEnergyOn/scale;
15421 AvNsigOn=nsigOn/scale;
15422 AvNbkgOn=nbkgOn/scale;
15423 AvRsigOn=nsigOn/Ton;
15424 AvRbkgOn=nbkgOn/Ton;
15425 AvEsigOn=fEnergySig/scale;
15426 AvEbkgOn=fEnergyBkg/scale;
15427 }
15428 scale=fNgrbs*fNbkg;
15429 if (scale)
15430 {
15431 AvSolidangleOff=fSolidangleOff/scale;
15432 AvNoff=nOff/scale;
15433 AvRoff=nOff/Toff;
15434 AvEoff=fEnergyOff/scale;
15435 }
15436
15437 // Statistics of the stacked event samples
15438 printf("\n *%-s::MakeBurstDataStats* Statistics of the stacked observed event samples. \n",ClassName());
15439 printf(" Integrated on-source exposure time of the %-i stacked time windows : %-g %-s \n",fNgrbs,Ton/fTfact,tu.Data());
15440 printf(" Integrated off-source exposure time of the %-i*%-i stacked time windows : %-g %-s \n",fNgrbs,fNbkg,Toff/fTfact,tu.Data());
15441 printf(" Total accumulated on-source solid angle : %-g sr in %-i stacked patches --> Average per patch : %-g sr \n",fSolidangleOn,fNgrbs,AvSolidangleOn);
15442 printf(" Total accumulated off-source solid angle : %-g sr in %-i*%-i stacked patches --> Average per patch : %-g sr \n",fSolidangleOff,fNgrbs,fNbkg,AvSolidangleOff);
15443 if (fSensarea>0) printf(" Area covered c.q. overlooked by the detector sensors : %-g m^2. \n",fSensarea);
15444 fSensarea*=1e4; // Convert to cm^2
15445
15446 printf(" *On source* Total number of recorded on-source events : %-g --> Average per patch : %-g events. \n",nOn,AvNon);
15447 printf(" --- Average recorded values per on-source patch --- \n");
15448 printf(" Steady event rate during the time window : %-g Hz",AvRon);
15449 if (AvSolidangleOn) printf(" --> %-g Hz sr^-1",AvRon/AvSolidangleOn);
15450 printf("\n");
15451 if (fSensarea>0)
15452 {
15453 printf(" Particle fluence : %-g cm^-2",AvNon/fSensarea);
15454 if (AvSolidangleOn) printf(" --> %-g cm^-2 sr^-1",AvNon/(fSensarea*AvSolidangleOn));
15455 printf("\n");
15456 printf(" Particle flux : %-g cm^-2 s^-1",AvRon/fSensarea);
15457 if (AvSolidangleOn) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",AvRon/(fSensarea*AvSolidangleOn));
15458 printf("\n");
15459 }
15460 printf(" Cumulated energy : %-g GeV",AvEon);
15461 if (AvSolidangleOn) printf(" --> %-g GeV sr^-1",AvEon/AvSolidangleOn);
15462 printf("\n");
15463 printf(" Power : %-g GeV/s",AvEon/TwinOn);
15464 if (AvSolidangleOn) printf(" --> %-g GeV s^-1 sr^-1",AvEon/(TwinOn*AvSolidangleOn));
15465 printf("\n");
15466 if (fSensarea>0)
15467 {
15468 printf(" Energy fluence : %-g GeV cm^-2",AvEon/fSensarea);
15469 if (AvSolidangleOn) printf(" --> %-g GeV cm^-2 sr^-1",AvEon/(fSensarea*AvSolidangleOn));
15470 printf("\n");
15471 printf(" Energy flux : %-g GeV cm^-2 s^-1",AvEon/(fSensarea*TwinOn));
15472 if (AvSolidangleOn) printf(" --> Intensity : %-g GeV cm^-2 s^-1 sr^-1",AvEon/(fSensarea*TwinOn*AvSolidangleOn));
15473 printf("\n");
15474 }
15475
15476 if (fNbkg)
15477 {
15478 printf(" *Off source* Total number of recorded off-source (background) events : %-g --> Average per patch : %-g events. \n",nOff,AvNoff);
15479 printf(" --- Average recorded values per off-source patch --- \n");
15480 printf(" Steady event rate during the time window : %-g Hz",AvRoff);
15481 if (AvSolidangleOff) printf(" --> %-g Hz sr^-1",AvRoff/AvSolidangleOff);
15482 printf("\n");
15483 if (fSensarea>0)
15484 {
15485 printf(" Particle fluence : %-g cm^-2",AvNoff/fSensarea);
15486 if (AvSolidangleOff) printf(" --> %-g cm^-2 sr^-1",AvNoff/(fSensarea*AvSolidangleOff));
15487 printf("\n");
15488 printf(" Particle flux : %-g cm^-2 s^-1",AvRoff/fSensarea);
15489 if (AvSolidangleOff) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",AvRoff/(fSensarea*AvSolidangleOff));
15490 printf("\n");
15491 }
15492 printf(" Cumulated energy : %-g GeV",AvEoff);
15493 if (AvSolidangleOff) printf(" --> %-g GeV sr^-1",AvEoff/AvSolidangleOff);
15494 printf("\n");
15495 printf(" Power : %-g GeV/s",AvEoff/TwinOff);
15496 if (AvSolidangleOff) printf(" --> %-g GeV s^-1 sr^-1",AvEoff/(TwinOn*AvSolidangleOff));
15497 printf("\n");
15498 if (fSensarea>0)
15499 {
15500 printf(" Energy fluence : %-g GeV cm^-2",AvEoff/fSensarea);
15501 if (AvSolidangleOff) printf(" --> %-g GeV cm^-2 sr^-1",AvEoff/(fSensarea*AvSolidangleOff));
15502 printf("\n");
15503 printf(" Energy flux : %-g GeV cm^-2 s^-1",AvEoff/(fSensarea*TwinOff));
15504 if (AvSolidangleOff) printf(" --> Intensity : %-g GeV cm^-2 s^-1 sr^-1",AvEoff/(fSensarea*TwinOff*AvSolidangleOff));
15505 printf("\n");
15506 }
15507 }
15508
15509 // On-source signal and background info is only available for simulated data
15510 if (!mode)
15511 {
15512 printf(" -(Unknown)- Total number of injected on-source signal events : %-i",nmugrb);
15513 if (fNgrbs) printf(" --> Average per patch : %-g events.",float(nmugrb)/float(fNgrbs));
15514 printf("\n");
15515 printf(" Total number of recorded on-source signal events : %-g",nsigOn);
15516 if (fNgrbs) printf(" --> Average per patch : %-g events.",nsigOn/float(fNgrbs));
15517 printf("\n");
15518 printf(" Total number of recorded on-source bkg events : %-g",nbkgOn);
15519 if (fNgrbs) printf(" --> Average per patch : %-g events.",nbkgOn/float(fNgrbs));
15520 printf("\n");
15521
15522 printf(" --- Average signal values per on-source patch --- \n");
15523 printf(" Steady event rate during the time window : %-g Hz",AvRsigOn);
15524 if (AvSolidangleOn) printf(" --> %-g Hz sr^-1",AvRsigOn/AvSolidangleOn);
15525 printf("\n");
15526 if (fSensarea>0)
15527 {
15528 printf(" Particle fluence : %-g cm^-2",AvNsigOn/fSensarea);
15529 if (AvSolidangleOn) printf(" --> %-g cm^-2 sr^-1",AvNsigOn/(fSensarea*AvSolidangleOn));
15530 printf("\n");
15531 printf(" Particle flux : %-g cm^-2 s^-1",AvRsigOn/fSensarea);
15532 if (AvSolidangleOn) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",AvRsigOn/(fSensarea*AvSolidangleOn));
15533 printf("\n");
15534 }
15535 printf(" Cumulated energy : %-g GeV",AvEsigOn);
15536 if (AvSolidangleOn) printf(" --> %-g GeV sr^-1",AvEsigOn/AvSolidangleOn);
15537 printf("\n");
15538 printf(" Power : %-g GeV/s",AvEsigOn/TwinOn);
15539 if (AvSolidangleOn) printf(" --> %-g GeV s^-1 sr^-1",AvEsigOn/(TwinOn*AvSolidangleOn));
15540 printf("\n");
15541 if (fSensarea>0)
15542 {
15543 printf(" Energy fluence : %-g GeV cm^-2",AvEsigOn/fSensarea);
15544 if (AvSolidangleOn) printf(" --> %-g GeV cm^-2 sr^-1",AvEsigOn/(fSensarea*AvSolidangleOn));
15545 printf("\n");
15546 printf(" Energy flux : %-g GeV cm^-2 s^-1",AvEsigOn/(fSensarea*TwinOn));
15547 if (AvSolidangleOn) printf(" --> Intensity : %-g GeV cm^-2 s^-1 sr^-1",AvEsigOn/(fSensarea*TwinOn*AvSolidangleOn));
15548 printf("\n");
15549 }
15550 printf(" --- Average background values per on-source patch --- \n");
15551 printf(" Steady event rate during the time window : %-g Hz",AvRbkgOn);
15552 if (AvSolidangleOn) printf(" --> %-g Hz sr^-1",AvRbkgOn/AvSolidangleOn);
15553 printf("\n");
15554 if (fSensarea>0)
15555 {
15556 printf(" Particle fluence : %-g cm^-2",AvNbkgOn/fSensarea);
15557 if (AvSolidangleOn) printf(" --> %-g cm^-2 sr^-1",AvNbkgOn/(fSensarea*AvSolidangleOn));
15558 printf("\n");
15559 printf(" Particle flux : %-g cm^-2 s^-1",AvRbkgOn/fSensarea);
15560 if (AvSolidangleOn) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",AvRbkgOn/(fSensarea*AvSolidangleOn));
15561 printf("\n");
15562 }
15563 printf(" Cumulated energy : %-g GeV",AvEbkgOn);
15564 if (AvSolidangleOn) printf(" --> %-g GeV sr^-1",AvEbkgOn/AvSolidangleOn);
15565 printf("\n");
15566 printf(" Power : %-g GeV/s",AvEbkgOn/TwinOn);
15567 if (AvSolidangleOn) printf(" --> %-g GeV s^-1 sr^-1",AvEbkgOn/(TwinOn*AvSolidangleOn));
15568 printf("\n");
15569 if (fSensarea>0)
15570 {
15571 printf(" Energy fluence : %-g GeV cm^-2",AvEbkgOn/fSensarea);
15572 if (AvSolidangleOn) printf(" --> %-g GeV cm^-2 sr^-1",AvEbkgOn/(fSensarea*AvSolidangleOn));
15573 printf("\n");
15574 printf(" Energy flux : %-g GeV cm^-2 s^-1",AvEbkgOn/(fSensarea*TwinOn));
15575 if (AvSolidangleOn) printf(" --> Intensity : %-g GeV cm^-2 s^-1 sr^-1",AvEbkgOn/(fSensarea*TwinOn*AvSolidangleOn));
15576 printf("\n");
15577 }
15578 }
15579 printf("\n");
15580
15581 // Create the simulated incoming signal Fluence vs. E histogram
15582 nsig=fBurstSigAeff.GetN();
15583 if (nsig && Ton)
15584 {
15585 TString nameS,titleS,nameF,titleF,nameE2F,titleE2F;
15586 nameS="hSigFluence";
15587 titleS="Stacked simulated incoming signal Fluence;Event energy [GeV];dN/dE [GeV^{-1} cm^{-2}]";
15588 nameF="hSigFlux";
15589 titleF="Simulated incoming signal Flux for a steady rate;Event energy [GeV];dN/dE [GeV^{-1} cm^{-2} s^{-1}]";
15590 nameE2F="hSigE2Flux";
15591 titleE2F="E-scaled simulated incoming signal Flux for a steady rate;Event energy [GeV];E^{2}dN/dE [GeV cm^{-2} s^{-1}]";
15592 TH1F* hS=(TH1F*)fBurstHistos.FindObject(nameS);
15593 TH1F* hF=(TH1F*)fBurstHistos.FindObject(nameF);
15594 TH1F* hE2F=(TH1F*)fBurstHistos.FindObject(nameE2F);
15595 if (hS)
15596 {
15597 delete hS;
15598 hS=new TH1F(nameS,titleS,100,0,-1);
15599 delete hF;
15600 hF=new TH1F(nameF,titleF,100,0,-1);
15601 delete hE2F;
15602 hE2F=new TH1F(nameE2F,titleE2F,100,0,-1);
15603 }
15604 else
15605 {
15606 hS=new TH1F(nameS,titleS,100,0,-1);
15607 fBurstHistos.Add(hS);
15608 hF=new TH1F(nameF,titleF,100,0,-1);
15609 fBurstHistos.Add(hF);
15610 hE2F=new TH1F(nameE2F,titleE2F,100,0,-1);
15611 fBurstHistos.Add(hE2F);
15612 }
15613
15614 hS->Sumw2();
15615 hF->Sumw2();
15616 hE2F->Sumw2();
15617
15618 Float_t E=0;
15619 Float_t Fluence=0;
15620 for (Int_t i=1; i<=nsig; i++)
15621 {
15622 Fluence=fBurstSigAeff.GetEntry(i,"Fluence");
15623 E=fBurstSigAeff.GetEntry(i,"E");
15624 if (Fluence>0)
15625 {
15626 hS->Fill(E,Fluence);
15627 hF->Fill(E,Fluence/Ton);
15628 hE2F->Fill(E,pow(E,2)*Fluence/Ton);
15629 }
15630 }
15631
15632 // Convert the histogram data into dN/dE
15633 // Flush the storage buffers to actually fill the histograms
15634 hS->BufferEmpty(1);
15635 hF->BufferEmpty(1);
15636 hE2F->BufferEmpty(1);
15637 Float_t binwidth=hS->GetBinWidth(1);
15638 if (binwidth>0)
15639 {
15640 hS->Scale(1./binwidth);
15641 hF->Scale(1./binwidth);
15642 hE2F->Scale(1./binwidth);
15643 }
15644 }
15645
15646 // Update internal statistics
15647 fBurstParameters->AddNamedSlot("TminOn");
15648 fBurstParameters->SetSignal(TminOn,"TminOn");
15649 fBurstParameters->AddNamedSlot("TmaxOn");
15650 fBurstParameters->SetSignal(TmaxOn,"TmaxOn");
15651 fBurstParameters->AddNamedSlot("TminOff");
15652 fBurstParameters->SetSignal(TminOff,"TminOff");
15653 fBurstParameters->AddNamedSlot("TmaxOff");
15654 fBurstParameters->SetSignal(TmaxOff,"TmaxOff");
15655 fBurstParameters->AddNamedSlot("DtwinOn");
15656 fBurstParameters->SetSignal(DtwinOn,"DtwinOn");
15657 fBurstParameters->AddNamedSlot("DtwinOff");
15658 fBurstParameters->SetSignal(DtwinOff,"DtwinOff");
15659 fBurstParameters->AddNamedSlot("NbkgWinOn");
15660 fBurstParameters->SetSignal(NbkgWinOn,"NbkgWinOn");
15661 fBurstParameters->AddNamedSlot("NbkgWinOff");
15662 fBurstParameters->SetSignal(NbkgWinOff,"NbkgWinOff");
15663 fBurstParameters->AddNamedSlot("TtotOn"); // The on-source total exposure time in sec.
15664 fBurstParameters->SetSignal(Ton,"TtotOn");
15665 fBurstParameters->AddNamedSlot("TtotOff"); // The off-source total exposure time ins sec.
15666 fBurstParameters->SetSignal(Toff,"TtotOff");
15667 fBurstParameters->AddNamedSlot("AvSolidangleOn"); // The average on-source solid angle
15668 fBurstParameters->SetSignal(AvSolidangleOn,"AvSolidangleOn");
15669 fBurstParameters->AddNamedSlot("AvSolidangleOff"); // The average off-source solid angle
15670 fBurstParameters->SetSignal(AvSolidangleOff,"AvSolidangleOff");
15671
15672 fBurstParameters->AddNamedSlot("rateOn");
15673 fBurstParameters->SetSignal(rateOn,"rateOn");
15674 fBurstParameters->AddNamedSlot("rateOff");
15675 fBurstParameters->SetSignal(rateOff,"rateOff");
15676
15677 // Update old parameters
15678 fBurstParameters->SetSignal(TminOn,"Tmin");
15679 fBurstParameters->SetSignal(TmaxOn,"Tmax");
15680 fBurstParameters->SetSignal(DtwinOn,"Dtwin");
15681 fBurstParameters->SetSignal(NbkgWinOn,"NbkgWin");
15682}
15683
15684void NcAstrolab::MatchBurstData(NcDevice& matches,Int_t i1,Int_t i2,Int_t itype,Int_t j1,Int_t j2,Int_t jtype)
15685{
15780
15781 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
15782 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
15783 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
15784 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
15785 Float_t fTmin=fBurstParameters->GetSignal("Tmin");
15786 Float_t fTmax=fBurstParameters->GetSignal("Tmax");
15787 Float_t fDawin=fBurstParameters->GetSignal("Dawin");
15788 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
15789 Float_t fMaxsigmatot=fBurstParameters->GetSignal("Maxsigmatot");
15790 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
15791
15792 // Update internal statistics to account for objects introduced by hand
15793 Int_t fNgrbs=GetNsignals(0);
15794 Int_t fNevts=GetNsignals(1);
15795 fBurstParameters->AddNamedSlot("Ngrbs");
15796 fBurstParameters->AddNamedSlot("Nevts");
15797 fBurstParameters->SetSignal(fNgrbs,"Ngrbs");
15798 fBurstParameters->SetSignal(fNevts,"Nevts");
15799
15800 // Initialize generic histograms for analysis
15802
15803 TString tu="d";
15804 if (fTunits==1) tu="hrs";
15805 if (fTunits==2) tu="s";
15806 if (fTunits==3) tu="ns";
15807 if (fTunits==4) tu="ps";
15808
15809 // Initialize the Device/Hit structure to contain the correlation info
15810 matches.Reset(1);
15811 matches.SetHitCopy(1);
15812
15813 TString name="Matches";
15814 TString title="Space and time matchings of NcAstrolab stored signals";
15815 matches.SetNameTitle(name,title);
15816 TString tux=tu;
15817 if (tu=="d") tux="days";
15818 if (tu=="hrs") tux="hours";
15819 if (tu=="s") tux="sec";
15820 TString namedamin="psimin in deg";
15821 TString namedtmin="dtmin in ";
15822 namedtmin+=tux;
15823 matches.AddNamedSlot(namedamin);
15824 matches.AddNamedSlot(namedtmin);
15825 matches.AddNamedSlot("ipsi");
15826 matches.AddNamedSlot("idt");
15827
15828 NcSignal data;
15829 TString nameda="psi in deg";
15830 TString namedt="t2-t1 in ";
15831 namedt+=tux;
15832 data.AddNamedSlot("type1");
15833 data.AddNamedSlot("index1");
15834 data.AddNamedSlot("type2");
15835 data.AddNamedSlot("index2");
15836 data.AddNamedSlot(nameda);
15837 data.AddNamedSlot(namedt);
15838
15839 if ((!itype || !jtype) && !fRefs)
15840 {
15841 printf(" *%-s::MatchBurstData* Error: itype=%-i jtype=%-i but no reference signals are present. \n",ClassName(),itype,jtype);
15842 return;
15843 }
15844
15845 if ((itype || jtype) && !fSigs)
15846 {
15847 printf(" *%-s::MatchBurstData* Error: itype=%-i jtype=%-i but no measurements are present. \n",ClassName(),itype,jtype);
15848 return;
15849 }
15850
15851 Int_t nrefs=0;
15852 if (fRefs) nrefs=fRefs->GetSize();
15853 Int_t nsigs=0;
15854 if (fSigs) nsigs=fSigs->GetSize();
15855
15856 // Make input data consistent with conventions
15857 if (itype) itype=1;
15858 if (jtype) jtype=1;
15859 if (!itype)
15860 {
15861 if (i2<1 || i2>nrefs) i2=nrefs;
15862 }
15863 else
15864 {
15865 if (i2<1 || i2>nsigs) i2=nsigs;
15866 }
15867 if (!jtype)
15868 {
15869 if (j2<1 || j2>nrefs) j2=nrefs;
15870 }
15871 else
15872 {
15873 if (j2<1 || j2>nsigs) j2=nsigs;
15874 }
15875
15876 if (i1<1 || j1<1 || i1>i2 || j1>j2)
15877 {
15878 printf(" *%-s::MatchBurstData* Inconsistent parameters: i1=%-i i2=%-i itype=%-i j1=%-i j2=%-i jtype=%-i. \n",ClassName(),i1,i2,itype,j1,j2,jtype);
15879 return;
15880 }
15881
15882 if (fDatype==1 && fMaxsigmatot<0)
15883 {
15884 printf(" *%-s::MatchBurstData* Incompatible parameter settings Datype=%-i Maxsigmatot=%-g \n",ClassName(),fDatype,fMaxsigmatot);
15885 printf(" === No matching analysis will be performed === \n");
15886 }
15887
15888 // The number of actually stored items
15889 Int_t ni=GetNsignals(itype);
15890 Int_t nj=GetNsignals(jtype);
15891
15892 // Additional text for histo titles to indicate scrambling of the corresponding data
15893 TString scrt=""; // Time scrambling
15894 TString scrp=""; // Position scrambling
15895 if (fTscmode>0) scrt="(scrambled)";
15896 if (fRscmode>0 || fTscmode==3) scrp="(scrambled)";
15897
15898 // The auto binned event-burst time difference histo for the full selected sample
15899 Int_t nbins=10000;
15900 title.Form("Time difference %-s between events and bursts for the full selected dataset;Tevent-Tburst in %-s;Counts",scrt.Data(),tux.Data());
15901 TH1F* hTdiff=new TH1F("hTdiff",title,nbins,1,0);
15902 if (ni && nj) hTdiff->SetBuffer(ni*nj);
15903
15904 // The auto binned event-burst angular difference histo for the full selected sample
15905 nbins=100;
15906 title.Form("Angular separation %-s between events and bursts for the full selected dataset;Opening angle in degrees;Counts",scrp.Data());
15907 TH1F* hAdiff=new TH1F("hAdiff",title,nbins,1,0);
15908 if (ni && nj) hAdiff->SetBuffer(ni*nj);
15909
15910 // Recording of the cumulated on-source reconstructed event energy
15911 fBurstParameters->AddNamedSlot("EnergyOn");
15912 fBurstParameters->AddNamedSlot("EnergyOff");
15913
15914 Double_t dang,dtime,diftheta;
15915 Int_t ix=0;
15916 Int_t jx=0;
15917 NcSignal* sxi=0;
15918 NcSignal* sxj=0;
15919 NcSignal* sxgrb=0;
15920 NcSignal* sxevt=0;
15921 Float_t sigmai=0;
15922 Float_t sigmaj=0;
15923 Float_t sigmagrb=0;
15924 Float_t sigmareco=0;
15925 Float_t sigmatot=0;
15926 Int_t id=0;
15927 Double_t dangmin=0;
15928 Double_t dtmin=0;
15929 Int_t idamin=0;
15930 Int_t idtmin=0;
15931 Bool_t first=kTRUE;
15932 Double_t dangmax=-1;
15933 Float_t Ereco=0;
15934 Float_t thlow=0;
15935 Float_t thup=0;
15936 Float_t thetagrb=0;
15937 Float_t solidangle=0;
15938 Int_t grbtype=0;
15939 Int_t evttype=0;
15940 Int_t k1=0;
15941 Int_t k2=0;
15942 Float_t zgrb=0;
15943 Int_t idx=0;
15944 NcTimestamp* tx=0;
15945 Nc3Vector rmu;
15946 Float_t thetamu=0;
15947 TH2* hAeffProfile=(TH2*)fBurstHistos.FindObject("hAeffProfile");
15948 Int_t gbin=0;
15949 Double_t Aeff=0;
15950 Double_t Fluence=0;
15951 for (Int_t bkgpatch=0; bkgpatch<=fNbkg; bkgpatch++) // On-source and Off-source patches
15952 {
15953 if (bkgpatch && !fTscmode && !fRscmode) break; // No background data without time and/or position scrambling
15954
15955 for (Int_t i=i1; i<=i2; i++)
15956 {
15957 sxi=GetSignal(i,itype);
15958 if (!sxi) continue;
15959
15960 sigmai=sxi->GetSignal("csigma");
15961
15962 if (itype && !fRecoangle) sigmai=fAngresfix;
15963
15964 for (Int_t j=j1; j<=j2; j++)
15965 {
15966 // Skip matching a signal with itself
15967 if (itype==jtype && i==j) continue;
15968
15969 sxj=GetSignal(j,jtype);
15970 if (!sxj) continue;
15971
15972 sigmaj=sxj->GetSignal("csigma");
15973
15974 if (jtype && !fRecoangle) sigmaj=fAngresfix;
15975
15976 if (itype==jtype) // Self correlations
15977 {
15978 sigmagrb=sigmai;
15979 sxgrb=sxi;
15980 grbtype=itype;
15981 sigmareco=sigmaj;
15982 sxevt=sxj;
15983 evttype=jtype;
15984 }
15985 else // Correlations between sources and measurements
15986 {
15987 if (itype)
15988 {
15989 sigmareco=sigmai;
15990 sxevt=sxi;
15991 evttype=itype;
15992 sigmagrb=sigmaj;
15993 sxgrb=sxj;
15994 grbtype=jtype;
15995 }
15996 else
15997 {
15998 sigmagrb=sigmai;
15999 sxgrb=sxi;
16000 grbtype=itype;
16001 sigmareco=sigmaj;
16002 sxevt=sxj;
16003 evttype=jtype;
16004 }
16005 }
16006
16007 sigmatot=-1;
16008 if (fSumsigmas==-1) sigmatot=sigmareco;
16009 if (fSumsigmas==0) sigmatot=sigmagrb;
16010 if (fSumsigmas==1) sigmatot=sigmagrb+sigmareco;
16011 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+sigmareco*sigmareco);
16012
16013 dangmax=-1;
16014 if (!fDatype) dangmax=fabs(fDawin);
16015 if (fDatype==1)
16016 {
16017 dangmax=0;
16018 if (fMaxsigmatot>0) dangmax=fabs(fDawin*fMaxsigmatot);
16019 }
16020 if (fDatype==2)
16021 {
16022 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
16023 }
16024
16025 // Flag incompatible input for sigma summation
16026 if (fDatype==1 && fMaxsigmatot<0) dangmax=-1;
16027
16028 ix=i;
16029 if (itype) ix=-i;
16030 jx=j;
16031 if (jtype) jx=-j;
16032
16033 if (tu!="hrs")
16034 {
16035 dang=GetSeparation(ix,jx,"deg",dtime,tu,1,bkgpatch,&diftheta);
16036 }
16037 else
16038 {
16039 dang=GetSeparation(ix,jx,"deg",dtime,"s",1,bkgpatch,&diftheta);
16040 dtime=dtime/3600.;
16041 }
16042
16043 if (!bkgpatch) // On-source data
16044 {
16045 // Fill the time difference histogram for full selected dataset
16046 if (hTdiff) hTdiff->Fill(dtime);
16047
16048 // Fill the angular difference histogram for full selected dataset
16049 if (hAdiff) hAdiff->Fill(dang);
16050
16051 // Initialize the On-source total solid angle for this source
16052 if (dangmax>=0 && !(sxgrb->GetSlotIndex("OmegaOn")))
16053 {
16054 sxgrb->AddNamedSlot("OmegaOn");
16055 if (fDawin<0) // Local zenith band
16056 {
16057 thlow=thetagrb-0.5*dangmax;
16058 thup=thetagrb+0.5*dangmax;
16059 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16060 }
16061 else // Circle around GRB position
16062 {
16063 thlow=0;
16064 thup=dangmax;
16065 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16066 }
16067 sxgrb->SetSignal(solidangle,"OmegaOn");
16068 }
16069 }
16070 else // Off-source c.q. background data
16071 {
16072 // Initialize the Off-source total solid angle for this source
16073 if (dangmax>=0 && !(sxgrb->GetSlotIndex("OmegaOff")))
16074 {
16075 sxgrb->AddNamedSlot("OmegaOff");
16076 if (fDawin<0) // Local zenith band
16077 {
16078 thlow=thetagrb-0.5*dangmax;
16079 thup=thetagrb+0.5*dangmax;
16080 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16081 }
16082 else // Circle around GRB position
16083 {
16084 thlow=0;
16085 thup=dangmax;
16086 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16087 }
16088 sxgrb->SetSignal(solidangle,"OmegaOff");
16089 }
16090 }
16091
16092 if (fDatype>=0)
16093 {
16094 if (fDawin<0) // Declination band
16095 {
16096 if (diftheta<thlow || diftheta>thup) continue;
16097 }
16098 else // Circle around the GRB
16099 {
16100 if (fabs(dang)>dangmax) continue;
16101 }
16102 }
16103
16104 if (fTmax>fTmin && (dtime<fTmin || dtime>fTmax)) continue;
16105
16106 if (!bkgpatch) // On-source data
16107 {
16108 // Tag this source of having an on-source matching event
16109 if (!(sxgrb->GetSlotIndex("HasMatchOn")))
16110 {
16111 sxgrb->AddNamedSlot("HasMatchOn");
16112 sxgrb->SetSignal(1,"HasMatchOn");
16113 }
16114
16115 data.Reset();
16116 name="Object1=";
16117 name+=sxi->GetName();
16118 title="Object2=";
16119 title+=sxj->GetName();
16120 id++;
16121 data.SetNameTitle(name,title);
16122 data.SetUniqueID(id);
16123 data.SetSignal(itype,"type1");
16124 data.SetSignal(i,"index1");
16125 data.SetSignal(jtype,"type2");
16126 data.SetSignal(j,"index2");
16127 data.SetSignal(dtime,namedt);
16128 data.SetSignal(dang,nameda);
16129 matches.AddHit(data);
16130
16131 // Update the maximum encountered dynamic On-source solid angle for this source
16132 if (fDatype==2)
16133 {
16134 if (fDawin<0) // Local zenith band
16135 {
16136 thlow=thetagrb-0.5*dangmax;
16137 thup=thetagrb+0.5*dangmax;
16138 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16139 }
16140 else // Circle around GRB position
16141 {
16142 thlow=0;
16143 thup=dangmax;
16144 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16145 }
16146 if (solidangle>sxgrb->GetSignal("OmegaOn")) sxgrb->SetSignal(solidangle,"OmegaOn");
16147 }
16148 }
16149 else // Off-source c.q. background data
16150 {
16151 // Tag this source of having an off-source matching event
16152 if (!(sxgrb->GetSlotIndex("HasMatchOff")))
16153 {
16154 sxgrb->AddNamedSlot("HasMatchOff");
16155 sxgrb->SetSignal(1,"HasMatchOff");
16156 }
16157
16158 // Update the maximum encountered dynamic Off-source solid angle for this source
16159 if (fDatype==2)
16160 {
16161 if (fDawin<0) // Local zenith band
16162 {
16163 thlow=thetagrb-0.5*dangmax;
16164 thup=thetagrb+0.5*dangmax;
16165 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16166 }
16167 else // Circle around GRB position
16168 {
16169 thlow=0;
16170 thup=dangmax;
16171 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16172 }
16173 if (solidangle>sxgrb->GetSignal("OmegaOff")) sxgrb->SetSignal(solidangle,"OmegaOff");
16174 }
16175 }
16176
16177 // Fill the histograms for the matching data
16178 if (!bkgpatch) // On-source data
16179 {
16180 Ereco=sxevt->GetSignal("E");
16181 zgrb=sxgrb->GetSignal("z");
16182 fBurstOnReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
16183 fBurstOnMatch.Enter(Ereco,dtime,dang,dtime/(zgrb+1.));
16184 fBurstParameters->AddSignal(Ereco,"EnergyOn");
16185 if (hAeffProfile)
16186 {
16187 nbins=(hAeffProfile->GetNbinsX())*(hAeffProfile->GetNbinsY());
16188 idx=GetSignalIndex(sxevt,evttype);
16189 if (idx>0)
16190 {
16191 tx=sxevt->GetTimestamp();
16192 GetSignal(rmu,"loc","T",tx,idx,evttype);
16193 thetamu=rmu.GetX(2,"sph","rad");
16194 gbin=hAeffProfile->FindFixBin(log10(Ereco),cos(thetamu));
16195 if (gbin>0 && gbin<nbins+1)
16196 {
16197 Aeff=hAeffProfile->GetBinContent(gbin);
16198 if (Aeff>0)
16199 {
16200 Fluence=1./Aeff;
16201 fBurstOnAeff.Enter(Aeff,Fluence,Ereco,dang);
16202 }
16203 }
16204 }
16205 }
16206
16207 // Record the data for the minimal encountered opening angle
16208 if (first || fabs(dang)<dangmin)
16209 {
16210 dangmin=fabs(dang);
16211 idamin=id;
16212 }
16213
16214 // Record the data for the minimal encountered time difference
16215 if (first || fabs(dtime)<fabs(dtmin))
16216 {
16217 dtmin=dtime;
16218 idtmin=id;
16219 }
16220
16221 first=kFALSE;
16222 }
16223 else // Off-source c.q. backgound data
16224 {
16225 Ereco=sxevt->GetSignal("E");
16226 zgrb=sxgrb->GetSignal("z");
16227 fBurstOffReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
16228 fBurstOffMatch.Enter(Ereco,dtime,dang,dtime/(zgrb+1.));
16229 fBurstParameters->AddSignal(Ereco,"EnergyOff");
16230 if (hAeffProfile)
16231 {
16232 nbins=(hAeffProfile->GetNbinsX())*(hAeffProfile->GetNbinsY());
16233 idx=GetSignalIndex(sxevt,evttype);
16234 if (idx>0)
16235 {
16236 tx=sxevt->GetTimestamp();
16237 GetSignal(rmu,"loc","T",tx,idx,evttype);
16238 thetamu=rmu.GetX(2,"sph","rad");
16239 gbin=hAeffProfile->FindFixBin(log10(Ereco),cos(thetamu));
16240 if (gbin>0 && gbin<nbins+1)
16241 {
16242 Aeff=hAeffProfile->GetBinContent(gbin);
16243 if (Aeff>0)
16244 {
16245 Fluence=1./Aeff;
16246 fBurstOffAeff.Enter(Aeff,Fluence,Ereco,dang);
16247 }
16248 }
16249 }
16250 }
16251 }
16252 } // End of the j-loop
16253 } // End of the i-loop
16254 } // End of loop over the patches
16255
16256 // Store the filled histograms in the storage container
16257 if (hTdiff->GetEntries()) fBurstHistos.Add(hTdiff);
16258 if (hAdiff->GetEntries()) fBurstHistos.Add(hAdiff);
16259
16260 // Recording of the On-source and Off-source total stacked solid angles
16261 name="SolidangleOn";
16262 fBurstParameters->AddNamedSlot(name);
16263 fBurstParameters->SetSignal(0,name);
16264 name="SolidangleOff";
16265 fBurstParameters->AddNamedSlot(name);
16266 fBurstParameters->SetSignal(0,name);
16267 if (itype==jtype) // Self correlations
16268 {
16269 grbtype=itype;
16270 k1=i1;
16271 k2=i2;
16272 }
16273 else // Correlations between sources and measurements
16274 {
16275 if (itype)
16276 {
16277 grbtype=jtype;
16278 k1=j1;
16279 k2=j2;
16280 }
16281 else
16282 {
16283 grbtype=itype;
16284 k1=i1;
16285 k2=i2;
16286 }
16287 }
16288 // Loop over all grbs in the selection
16289 for (Int_t k=k1; k<=k2; k++)
16290 {
16291 sxgrb=GetSignal(k,grbtype);
16292 if (!sxgrb) continue;
16293
16294 solidangle=sxgrb->GetSignal("OmegaOn");
16295 fBurstParameters->AddSignal(solidangle,"SolidangleOn");
16296
16297 solidangle=sxgrb->GetSignal("OmegaOff");
16298 fBurstParameters->AddSignal(solidangle*float(fNbkg),"SolidangleOff");
16299 }
16300
16301 // Store the data for the minimal encountered opening angle and time difference
16302 matches.SetSignal(dangmin,namedamin);
16303 matches.SetSignal(dtmin,namedtmin);
16304 matches.SetSignal(idamin,"ipsi");
16305 matches.SetSignal(idtmin,"idt");
16306
16307 // Determine and list the burst statistics
16309}
16310
16311void NcAstrolab::MatchBurstData(NcDevice& matches,TString name,Int_t itype,Int_t j1,Int_t j2,Int_t jtype)
16312{
16411
16412 Int_t i=GetSignalIndex(name,itype);
16413
16414 if (i==-1) // Add the info for the requested Solar system object if not already stored
16415 {
16416 SetSolarSystem(name,0,itype);
16417 i=GetSignalIndex(name,itype);
16418 if (i>0) fSolUpdate=1;
16419 }
16420
16421 if (i<1)
16422 {
16423 printf(" *%-s::MatchBurstData* Object %-s not found for itype=%-i. \n",ClassName(),name.Data(),itype);
16424 }
16425 else
16426 {
16427 MatchBurstData(matches,i,i,itype,j1,j2,jtype);
16428 }
16429
16430 fSolUpdate=0;
16431}
16432
16434{
16447
16448 // Retreive the needed parameters
16449 Float_t fT90min=fBurstParameters->GetSignal("T90min");
16450 Float_t fT90max=fBurstParameters->GetSignal("T90max");
16451 Float_t fAlphasig=fBurstParameters->GetSignal("Alphasig");
16452 Float_t fAlphabkg=fBurstParameters->GetSignal("Alphabkg");
16453 Float_t fAvgrbz=fBurstParameters->GetSignal("Avgrbz");
16454 Float_t fAvgrbt90=fBurstParameters->GetSignal("Avgrbt90");
16455 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
16456
16457 TString tu="days";
16458 if (fTunits==1) tu="hours";
16459 if (fTunits==2) tu="sec";
16460 if (fTunits==3) tu="ns";
16461 if (fTunits==4) tu="ps";
16462
16463 TString title;
16464 TString s;
16465
16466 // Initialize the On-source and Off-source data samples
16467 fBurstOnReco.Reset();
16468 fBurstOnMatch.Reset();
16469 fBurstSigReco.Reset();
16470 fBurstSignal.Reset();
16471 fBurstOffReco.Reset();
16472 fBurstOffMatch.Reset();
16473 fBurstOnReco.SetNameTitle("BurstOnReco","On-source reco data");
16474 fBurstOnReco.SetStoreMode();
16475 fBurstOnReco.SetNames("zburst","sigmaburst","sigmareco","sigmacomb");
16476 fBurstOnMatch.SetNameTitle("BurstOnMatch","On-source matching data");
16477 fBurstOnMatch.SetStoreMode();
16478 fBurstOnMatch.SetNames("E","dtime","dang","dtimez");
16479 fBurstSigReco.SetNameTitle("BurstSigReco","Simulated signal reco data");
16480 fBurstSigReco.SetStoreMode();
16481 fBurstSigReco.SetNames("zburst","sigmaburst","sigmareco","sigmacomb");
16482 fBurstSignal.SetNameTitle("BurstSignal","Simulated signal events");
16483 fBurstSignal.SetStoreMode();
16484 fBurstSignal.SetNames("E","dtime","dang","dtimez");
16485 fBurstOffReco.SetNameTitle("BurstOffReco","Off-source reco data");
16486 fBurstOffReco.SetStoreMode();
16487 fBurstOffReco.SetNames("zburst","sigmaburst","sigmareco","sigmacomb");
16488 fBurstOffMatch.SetNameTitle("BurstOffMatch","Off-source matching data");
16489 fBurstOffMatch.SetStoreMode();
16490 fBurstOffMatch.SetNames("E","dtime","dang","dtimez");
16491 fBurstOnAeff.Reset();
16492 fBurstOffAeff.Reset();
16493 fBurstSigAeff.Reset();
16494 fBurstOnAeff.SetNameTitle("BurstOnAeff","On-source track Aeff, E and dang data");
16495 fBurstOnAeff.SetStoreMode();
16496 fBurstOnAeff.SetNames("Aeff","Fluence","E","dang");
16497 fBurstOffAeff.SetNameTitle("BurstOffAeff","Off-source track Aeff, E and dang data");
16498 fBurstOffAeff.SetStoreMode();
16499 fBurstOffAeff.SetNames("Aeff","Fluence","E","dang");
16500 fBurstSigAeff.SetNameTitle("BurstSigAeff","Simulated signal track Aeff, E and dang data");
16501 fBurstSigAeff.SetStoreMode();
16502 fBurstSigAeff.SetNames("Aeff","Fluence","E","dang");
16503
16504 // Set default simulation signal and background energy spectra if needed
16505 if (!mode)
16506 {
16507 TH1* edist=0;
16508 edist=(TH1*)fBurstHistos.FindObject("hSigEprofile");
16509 if (!edist) MakeBurstEnergydist("SigE",fAlphasig,10000);
16510 edist=(TH1*)fBurstHistos.FindObject("hBkgEprofile");
16511 if (!edist) MakeBurstEnergydist("BkgE",fAlphabkg,10000);
16512 }
16513
16515 // Some statistics from the loaded data //
16517
16518 Int_t fNgrbs=GetNsignals(0);
16519 Int_t fNevts=GetNsignals(1);
16520
16521 Float_t xmin=0;
16522 Float_t xmax=0;
16523 Float_t range=0;
16524 Int_t nbins=100;
16525 Float_t binsize=0;
16526 Int_t srcbufsize=10000;
16527 if (fNgrbs && fNgrbs<srcbufsize) srcbufsize=fNgrbs;
16528 Int_t evtbufsize=10000;
16529 if (fNevts && fNevts<evtbufsize) evtbufsize=fNevts;
16530
16531 // Creation of the burst redshift histo
16532 title.Form("Redshifts for the selected source sample;Redshift;Counts");
16533 TH1F* hSourceZ=new TH1F("hSourceZ",title,nbins,1,0);
16534 hSourceZ->SetBuffer(srcbufsize);
16535
16536 // Creation of the corresponding physical distance histo
16537 nbins=100;
16538 title.Form("Distances for the selected source sample derived from the redshifts;Physical distance in Mpc;Counts");
16539 TH1F* hSourceD=new TH1F("hSourceD",title,nbins,xmin,xmax);
16540 hSourceD->SetBuffer(srcbufsize);
16541
16542 // Creation of the burst t90 duration histo
16543 xmin=-5;
16544 if (fabs(fT90min)>0) xmin=log10(fabs(fT90min));
16545 xmax=5;
16546 if (fT90max>0) xmax=log10(fT90max);
16547 range=xmax-xmin;
16548 binsize=0.2; // Bins of 0.2
16549 nbins=TMath::Nint(range/binsize);
16550 if (nbins<1)
16551 {
16552 xmin=xmin-1.;
16553 xmax=xmax+1.;
16554 nbins=10;
16555 }
16556 title.Form("Burst durations for the selected source sample;Burst duration ^{10}log(T90) in sec.;Counts");
16557 TH1F* hBurstT90=new TH1F("hBurstT90",title,nbins,xmin,xmax);
16558
16559 // Creation of the full selected sample burst position uncertainty histo with automatic binning
16560 nbins=100;
16561 title.Form("Position uncertainties for the selected source sample;Position angular uncertainty (sigma in degrees);Counts");
16562 TH1F* hSigmaSource=new TH1F("hSigmaSource",title,nbins,1,0);
16563 hSigmaSource->SetBuffer(srcbufsize);
16564
16565 // Creation of the real event reconstructed energy histo with automatic binning
16566 TH1F* hEreco=0;
16567 nbins=1000;
16568 if (mode==1)
16569 {
16570 title.Form("Reconstructed energy for the full selected real event sample;Reconstructed event energy in GeV;Counts");
16571 hEreco=new TH1F("hEreco",title,nbins,1,0);
16572 hEreco->SetBuffer(evtbufsize);
16573 }
16574
16575 // Creation of the injected source signal event energy histo with automatic binning
16576 TH1F* hSigE=0;
16577 TH1F* hSigEzcor=0;
16578 nbins=1000;
16579 if (mode==0)
16580 {
16581 title.Form("Injected signal energy at the source;Event energy in GeV;Counts");
16582 hSigE=new TH1F("hSigE",title,nbins,1,0);
16583 fBurstHistos.Add(hSigE);
16584 title.Form("(Redshift corrected) injected signal energy arriving at Earth;Event energy in GeV;Counts");
16585 hSigEzcor=new TH1F("hSigEzcor",title,nbins,1,0);
16586 fBurstHistos.Add(hSigEzcor);
16587 }
16588
16589 // Creation of the full selected sample event reconstruction uncertainty histo with automatic binning
16590 TH1F* hSigmaReco=0;
16591 nbins=100;
16592 title.Form("Event reconstruction uncertainties for the full selected sample;Event angular reconstruction uncertainty (sigma in degrees);Counts");
16593 hSigmaReco=new TH1F("hSigmaReco",title,nbins,1,0);
16594 hSigmaReco->SetBuffer(evtbufsize);
16595
16596 // Fill the generic source c.q. burst histograms
16597 NcSignal* sx=0;
16598 Float_t zgrb=0;
16599 Double_t dgrb=0;
16600 Float_t t90grb=0;
16601 Float_t sigmagrb=0;
16602 NcSample zsample;
16603 zsample.SetStoreMode();
16604 NcSample t90sample;
16605 t90sample.SetStoreMode();
16606 NcSample sigmasample;
16607 sigmasample.SetStoreMode();
16608 Int_t nsig=GetNsignals(0,1);
16609 for (Int_t i=1; i<=nsig; i++)
16610 {
16611 sx=GetSignal(i,0);
16612
16613 if (!sx) continue;
16614
16615 zgrb=sx->GetSignal("z");
16616 dgrb=GetPhysicalDistance(zgrb);
16617 t90grb=sx->GetSignal("T90");
16618 sigmagrb=sx->GetSignal("csigma");
16619
16620 hSourceZ->Fill(zgrb);
16621 hSourceD->Fill(dgrb);
16622 if (t90grb>0) hBurstT90->Fill(log10(t90grb));
16623 hSigmaSource->Fill(sigmagrb);
16624
16625 if (fAvgrbz<0) zsample.Enter(zgrb);
16626 if (fAvgrbt90<0) t90sample.Enter(t90grb);
16627 sigmasample.Enter(sigmagrb);
16628 }
16629
16630 // Add the filled histograms to the storage container
16631 if (hSourceZ->GetEntries()) fBurstHistos.Add(hSourceZ);
16632 if (hSourceD->GetEntries()) fBurstHistos.Add(hSourceD);
16633 if (hBurstT90->GetEntries()) fBurstHistos.Add(hBurstT90);
16634 if (hSigmaSource->GetEntries()) fBurstHistos.Add(hSigmaSource);
16635
16636 // Determine median redshift if requested
16637 if (fAvgrbz<0)
16638 {
16639 fAvgrbz=zsample.GetMedian(1);
16640 fAvgrbz*=-1.;
16641 }
16642
16643 // Determine median T90 duration if requested
16644 if (fAvgrbt90<0)
16645 {
16646 fAvgrbt90=t90sample.GetMedian(1);
16647 fAvgrbt90*=-1.;
16648 }
16649
16650 Float_t fAvgrbsigma=sigmasample.GetMedian(1);
16651
16652 // Fill the generic event histograms
16653 Float_t sigmareco=0;
16654 Float_t Ereco=0;
16655 nsig=GetNsignals(1,1);
16656 for (Int_t i=1; i<=nsig; i++)
16657 {
16658 sx=GetSignal(i,1);
16659
16660 if (!sx) continue;
16661
16662 sigmareco=sx->GetSignal("csigma");
16663 Ereco=sx->GetSignal("E");
16664
16665 if (hSigmaReco) hSigmaReco->Fill(sigmareco);
16666 if (hEreco) hEreco->Fill(Ereco);
16667 }
16668
16669 // Add the filled histograms to the storage container
16670 if (hSigmaReco->GetEntries()) fBurstHistos.Add(hSigmaReco);
16671 if (hEreco)
16672 {
16673 if (hEreco->GetEntries()) fBurstHistos.Add(hEreco);
16674 }
16675
16676 // Update internal statistics
16677 fBurstParameters->SetSignal(fAvgrbz,"Avgrbz");
16678 fBurstParameters->SetSignal(fAvgrbt90,"Avgrbt90");
16679 fBurstParameters->AddNamedSlot("Avgrbsigma");
16680 fBurstParameters->SetSignal(fAvgrbsigma,"Avgrbsigma");
16681}
16682
16684{
16690
16691 // Retreive the needed parameters
16692 Float_t fGrbnu=fBurstParameters->GetSignal("Grbnu");
16693 Int_t fNgrbs=TMath::Nint(fBurstParameters->GetSignal("Ngrbs"));
16694 Int_t fInburst=TMath::Nint(fBurstParameters->GetSignal("Inburst"));
16695 Float_t fDtnu=fBurstParameters->GetSignal("Dtnu");
16696 Float_t fDtnus=fBurstParameters->GetSignal("Dtnus");
16697 Float_t fTimres=fBurstParameters->GetSignal("Timres");
16698 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
16699 Float_t fDawin=fBurstParameters->GetSignal("Dawin");
16700 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
16701 Int_t fEzcor=TMath::Nint(fBurstParameters->GetSignal("Ezcor"));
16702 Int_t fPDFsigE=TMath::Nint(fBurstParameters->GetSignal("PDFsigE"));
16703 Float_t fEmin=fBurstParameters->GetSignal("Emin");
16704 Float_t fEmax=fBurstParameters->GetSignal("Emax");
16705 Int_t fKinangle=TMath::Nint(fBurstParameters->GetSignal("Kinangle"));
16706 Float_t fAngresmin=fBurstParameters->GetSignal("Angresmin");
16707 Float_t fAngresmax=fBurstParameters->GetSignal("Angresmax");
16708 Float_t fAngresfix=fBurstParameters->GetSignal("Angresfix");
16709 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
16710
16711 // Deactivate redshift correction for source signal events from archival observed data
16712 if (!fPDFsigE)
16713 {
16714 fEzcor=0;
16715 fBurstParameters->SetSignal(0,"Ezcor");
16716 }
16717
16718 Int_t nmu=int(fabs(fGrbnu)*float(fNgrbs));
16719 Int_t jgrb=0;
16720 NcSignal* sx=0;
16721 NcTimestamp* tx=0;
16722 Float_t t90grb=0;
16723 Float_t zgrb=0;
16724 Float_t sigmagrb=0;
16725 NcPosition rgrb;
16726 NcPosition rgrb2;
16727 Float_t dt=0;
16728 Double_t dgrb=0;
16729 Double_t thetagrb=0;
16730 Double_t phigrb=0;
16731 Float_t dang=0;
16732 Float_t dangmax=0;
16733 Float_t dangmaxOn=0;
16734 NcPosition rmu;
16735 Double_t E=0;
16736 Double_t sigmareco=0;
16737 Float_t sigmatot=0;
16738 Float_t OmegaOn=0; // The current on-source solid angle probed for a certain GRB
16739 Float_t thlow=0;
16740 Float_t thup=0;
16741 Float_t solidangle=0;
16742 Int_t fixedwinset=0; // Flag to indicate whether a fixed angular search window was set (1) or not (0) for this burst
16743
16744 TH1* hSigE=(TH1*)fBurstHistos.FindObject("hSigE");
16745 TH1* hSigEzcor=(TH1*)fBurstHistos.FindObject("hSigEzcor");
16746 TH2* hAeffProfile=(TH2*)fBurstHistos.FindObject("hAeffProfile");
16747
16748 // The bin numbers and Aeff value in the AeffProfile for the (E,theta) of the track
16749 Int_t nbins=0;
16750 if (hAeffProfile) nbins=(hAeffProfile->GetNbinsX())*(hAeffProfile->GetNbinsY());
16751 Int_t gbin=0; // The global bin number in the histogram
16752 Double_t Aeff=0;
16753 Double_t Fluence=0;
16754 Double_t thetamu=0;
16755
16756 while (nmugrb<nmu)
16757 {
16758 // Pick randomly one of the stored GRBs
16759 jgrb=int(fRan->Uniform(0.,float(fNgrbs)));
16760 if (jgrb==0) jgrb=1;
16761 sx=GetSignal(jgrb);
16762
16763 if (!sx) continue;
16764
16765 tx=sx->GetTimestamp();
16766 GetSignal(dgrb,thetagrb,"deg",phigrb,"deg","loc",tx,jgrb);
16767 rgrb.SetPosition(1,thetagrb,phigrb,"sph","deg");
16768 zgrb=sx->GetSignal("z");
16769 t90grb=sx->GetSignal("T90");
16770 sigmagrb=sx->GetSignal("csigma");
16771 fixedwinset=TMath::Nint(sx->GetSignal("fixedwinset"));
16772 dangmaxOn=sx->GetSignal("dangmaxOn");
16773 OmegaOn=sx->GetSignal("OmegaOn");
16774
16775 dangmax=dangmaxOn;
16776
16777 // Obtain actual GRB position
16778 rgrb2.Load(rgrb);
16779 SmearPosition(rgrb2,sigmagrb);
16780
16781 nmugrb++;
16782
16783 if (!fInburst) // Neutrino and gamma production decoupled
16784 {
16785 if (fDtnus<0) // Sigma in units of T90
16786 {
16787 dt=fRan->Gauss(fDtnu,fabs(fDtnus)*t90grb);
16788 }
16789 else // Sigma in seconds
16790 {
16791 dt=fRan->Gauss(fDtnu,fDtnus);
16792 }
16793 dt=dt*(zgrb+1.);
16794 }
16795 else // Coupled neutrino and gamma production
16796 {
16797 if (fDtnus<0) // Sigma in units of T90
16798 {
16799 dt=fRan->Gauss(fDtnu*t90grb,fabs(fDtnus)*t90grb);
16800 }
16801 else // Sigma in seconds
16802 {
16803 dt=fRan->Gauss(fDtnu*t90grb,fDtnus);
16804 }
16805 }
16806 if (fTimres>0) dt=fRan->Gauss(dt,fTimres);
16807
16808 // Convert dt from seconds to the selected Tunits
16809 dt=dt/fTfact;
16810
16811 // The direction of the GRB signal
16812 rmu.Load(rgrb2);
16813
16814 // The energy of the GRB signal
16816
16817 if (hSigE) hSigE->Fill(E);
16818
16819 // Reduce the energy due to the cosmological redshift effect
16820 if (fEzcor) E=E/(zgrb+1.);
16821
16822 if (hSigEzcor) hSigEzcor->Fill(E);
16823
16824 if (E<0 || E<fEmin || E>fEmax) continue;
16825
16826 // Modification to account for the neutrino-lepton kinematic opening angle
16827 if (fKinangle>0)
16828 {
16829 Int_t mode=fKinangle-1;
16830 Double_t ang=GetNeutrinoAngle(E,"deg",mode);
16831 if (ang>0) ShiftPosition(rmu,ang);
16832 }
16833
16834 // Smearing according to the reconstruction angular resolution
16835 sigmareco=GetBurstRecoAngres(E,E);
16836 if (sigmareco<0) sigmareco=fAngresfix;
16837
16838 if (sigmareco<fAngresmin || sigmareco>fAngresmax) continue;
16839
16840 SmearPosition(rmu,sigmareco);
16841
16842 // Determine angular difference w.r.t. the presumed GRB position
16843 dang=rgrb.GetOpeningAngle(rmu,"deg");
16844
16845 sigmatot=-1;
16846 if (fSumsigmas==-1) sigmatot=sigmareco;
16847 if (fSumsigmas==0) sigmatot=sigmagrb;
16848 if (fSumsigmas==1) sigmatot=sigmagrb+sigmareco;
16849 if (fSumsigmas==2) sigmatot=sqrt(sigmagrb*sigmagrb+sigmareco*sigmareco);
16850
16851 // Determine the dynamic angular window including the track reco uncertainty
16852 if (!fixedwinset)
16853 {
16854 dangmax=-1;
16855 if (sigmatot>=0) dangmax=fabs(fDawin*sigmatot);
16856 }
16857
16858 if (fDatype>=0 && dang>dangmax) continue;
16859
16860 fBurstOnReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
16861 fBurstOnMatch.Enter(E,dt,dang,dt/(zgrb+1.));
16862 fBurstSigReco.Enter(zgrb,sigmagrb,sigmareco,sigmatot);
16863 fBurstSignal.Enter(E,dt,dang,dt/(zgrb+1.));
16864 fBurstParameters->AddSignal(E,"EnergyOn");
16865 fBurstParameters->AddSignal(E,"EnergySig");
16866 if (hAeffProfile)
16867 {
16868 thetamu=rmu.GetX(2,"sph","rad");
16869 gbin=hAeffProfile->FindFixBin(log10(E),cos(thetamu));
16870 if (gbin>0 && gbin<nbins+1)
16871 {
16872 Aeff=hAeffProfile->GetBinContent(gbin);
16873 if (Aeff>0)
16874 {
16875 Fluence=1./Aeff;
16876 fBurstOnAeff.Enter(Aeff,Fluence,E,dang);
16877 fBurstSigAeff.Enter(Aeff,Fluence,E,dang);
16878 }
16879 }
16880 }
16881
16882 if (fixedwinset) continue;
16883
16884 // Update the dynamic On-source maximum (solid) angle that is encountered for this burst
16885 if (fDawin<0) // Local zenith band
16886 {
16887 thlow=thetagrb-0.5*dangmax;
16888 thup=thetagrb+0.5*dangmax;
16889 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16890 }
16891 else // Circle around GRB position
16892 {
16893 thlow=0;
16894 thup=dangmax;
16895 solidangle=GetSolidAngle(thlow,thup,"deg",0,360,"deg");
16896 }
16897 if (dangmax>dangmaxOn) sx->SetSignal(dangmax,"dangmaxOn");
16898 if (solidangle>OmegaOn) sx->SetSignal(solidangle,"OmegaOn");
16899 }
16900}
16901
16902TH1* NcAstrolab::GetBurstBayesianSignalRate(Double_t p,Double_t& rlow,Double_t& rup,Int_t n)
16903{
16934
16935 rlow=0;
16936 rup=0;
16937
16938 // The number of on-source and off-source patches
16939 Int_t fNgrbs=GetNsignals(0);
16940 Int_t fNbkg=TMath::Nint(fBurstParameters->GetSignal("Nbkg"));
16941
16942 // The recorded (stacked) on-source and off-source number of events
16943 Double_t Non=fBurstOnMatch.GetN();
16944 Double_t Noff=fBurstOffMatch.GetN();
16945
16946 if (fNgrbs<=0 || fNbkg<=0 || Non<=0 || Noff<=0)
16947 {
16948 printf(" \n *%-s::GetBurstBayesianSignalRate* \n",ClassName());
16949 if (fNgrbs<=0 || Non<=0) printf(" === No on-source data available === \n");
16950 if (fNbkg<=0 || Noff<=0) printf(" === No off-source data available === \n");
16951 return 0;
16952 }
16953
16954 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
16955 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
16956
16957 TString tu="days";
16958 if (fTunits==1) tu="hours";
16959 if (fTunits==2) tu="sec";
16960 if (fTunits==3) tu="ns";
16961 if (fTunits==4) tu="ps";
16962
16963 // The (stacked) on-source and off-source solid angles that were probed
16964 Double_t fSolidangleOn=fBurstParameters->GetSignal("SolidangleOn");
16965 Double_t fSolidangleOff=fBurstParameters->GetSignal("SolidangleOff");
16966 Double_t fAvSolidangleOn=fBurstParameters->GetSignal("AvSolidangleOn");
16967 Double_t fAvSolidangleOff=fBurstParameters->GetSignal("AvSolidangleOff");
16968 Double_t Ra=-1;
16969 if (fAvSolidangleOff) Ra=fAvSolidangleOn/fAvSolidangleOff;
16970
16971 // The integrated on-source and off-source exposure times in seconds
16972 Double_t Ton=fBurstParameters->GetSignal("TtotOn");
16973 Double_t Toff=fBurstParameters->GetSignal("TtotOff");
16974
16975 // The Bayesian posterior background and signal rate PDFs
16976 TF1 fbkgrpdf=GetBackgroundRatePDF(Noff,Toff);
16977 TF1 fsigrpdf=GetSignalRatePDF(Non,Ton,Noff,Toff,Ra);
16978
16979 Double_t rmode=fsigrpdf.GetMaximumX();
16980 Double_t bkgrmode=fbkgrpdf.GetMaximumX();
16981
16982 // Determine the "p%" credible interval for the signal rate
16983 Float_t frac=0;
16984 frac=GetCredibleInterval(fsigrpdf,p,rlow,rup,n);
16985
16986 // Provide the signal and background rate PDFs as histograms in the output file
16987 fbkgrpdf.SetRange(0,3.*Noff/Toff);
16988 fbkgrpdf.SetNpx(n);
16989 TH1* hBkgRatePDF=(TH1*)fbkgrpdf.GetHistogram()->Clone();
16990 hBkgRatePDF->SetName("hBkgRatePDF");
16991 fBurstHistos.Add(hBkgRatePDF);
16992 fsigrpdf.SetRange(0,3.*Non/Ton);
16993 fsigrpdf.SetNpx(n);
16994 TH1* hSigRatePDF=(TH1*)fsigrpdf.GetHistogram()->Clone();
16995 hSigRatePDF->SetName("hSigRatePDF");
16996 fBurstHistos.Add(hSigRatePDF);
16997
16998 printf("\n *%-s::GetBurstBayesianSignalRate* Credible interval [rlow,rup] for p=%-g%% with a precision of 1/%-i \n",ClassName(),p,n);
16999
17000 // Issue a warning in case variable angular cones based on actual track reco sigmas were used.
17001 // This can induce large variations in the on-source and off-source event counts
17002 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
17003 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
17004 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
17005
17006 if (fRecoangle && fSumsigmas && fDatype==2)
17007 {
17008 printf(" === Warning: Variable angular cones based on actual track reconstruction sigmas were used. \n");
17009 printf(" Large variations between the on-source and off-source background counts may be present. \n");
17010 }
17011
17012 printf(" The %-g%% credible interval from the Bayesian posterior signal pdf : [%-g,%-g] Hz \n",100.*frac,rlow,rup);
17013 printf(" Modes of the on-source posterior PDFs : Signal=%-g Hz Background=%-g Hz",rmode,bkgrmode);
17014 if (bkgrmode) printf(" Signal/Background=%-g",rmode/bkgrmode);
17015 printf("\n");
17016 printf(" The following signal and background rate PDF histograms have been generated : \n");
17017 printf(" ... %-s : %-s \n",hSigRatePDF->GetName(),hSigRatePDF->GetTitle());
17018 printf(" ... %-s : %-s \n",hBkgRatePDF->GetName(),hBkgRatePDF->GetTitle());
17019
17020 // The area covered c.q. overlooked by the detector sensors
17021 Float_t fSensarea=fBurstParameters->GetSignal("Sensarea");
17022 fSensarea*=1e4; // Convert to cm^2
17023
17024 printf(" Integrated on-source exposure time of the %-i stacked time windows : %-g %-s \n",fNgrbs,Ton/fTfact,tu.Data());
17025 printf(" Integrated off-source exposure time of the %-i*%-i stacked time windows : %-g %-s \n",fNgrbs,fNbkg,Toff/fTfact,tu.Data());
17026 printf(" Total accumulated on-source solid angle : %-g sr in %-i stacked patches --> Average per patch : %-g sr \n",fSolidangleOn,fNgrbs,fAvSolidangleOn);
17027 printf(" Total accumulated off-source solid angle : %-g sr in %-i*%-i stacked patches --> Average per patch : %-g sr \n",fSolidangleOff,fNgrbs,fNbkg,fAvSolidangleOff);
17028 if (fSensarea>0) printf(" Area covered c.q. overlooked by the detector sensors : %-g cm^2. \n",fSensarea);
17029
17030 printf(" Total number of recorded on-source events : %-g --> Average per patch : %-g events. \n",Non,Non/float(fNgrbs));
17031 printf(" Total number of recorded off-source events : %-g --> Average per patch : %-g events. \n",Noff,Noff/float(fNgrbs*fNbkg));
17032
17033 // Provide statistics for the signal rate PDF mode, lower and upper boundaries as well as the mode of the background PDF
17034 for (Int_t i=1; i<3; i++)
17035 {
17036 printf(" ********************************************************************** \n");
17037 if (i==1)
17038 {
17039 printf(" * Accumulated (stacked) on-source values based on the posterior PDFs * \n");
17040 }
17041 else
17042 {
17043 printf(" * Average values per on-source patch based on the posterior PDFs * \n");
17044 }
17045 printf(" ********************************************************************** \n");
17046
17047 TString text;
17048
17049 printf(" *Lower bound* Steady signal event rate during each time window : %-g Hz",rlow);
17050 if (fAvSolidangleOn) printf(" --> %-g Hz sr^-1",rlow/fAvSolidangleOn);
17051 printf("\n");
17052 text.Form("CL%-iLower",TMath::Nint(p));
17053 ListBurstSignalStats(rlow,i,text);
17054
17055 printf(" *Mode* Steady signal event rate during each time window : %-g Hz",rmode);
17056 if (fAvSolidangleOn) printf(" --> %-g Hz sr^-1",rmode/fAvSolidangleOn);
17057 printf("\n");
17058 ListBurstSignalStats(rmode,i,"Mode");
17059
17060 printf(" *Upper bound* Steady signal event rate during each time window : %-g Hz",rup);
17061 if (fAvSolidangleOn) printf(" --> %-g Hz sr^-1",rup/fAvSolidangleOn);
17062 printf("\n");
17063 text.Form("CL%-iUpper",TMath::Nint(p));
17064 ListBurstSignalStats(rup,i,text);
17065
17066 printf(" *Background* Steady background event rate during each time window : %-g Hz",bkgrmode);
17067 if (fAvSolidangleOn) printf(" --> %-g Hz sr^-1",bkgrmode/fAvSolidangleOn);
17068 printf("\n");
17069
17070 ListBurstSignalStats(bkgrmode,-i);
17071 }
17072 return hSigRatePDF;
17073}
17074
17075Double_t NcAstrolab::GetBurstTotalFluence(Double_t nsig,TString str)
17076{
17092
17093 Double_t Ton=fBurstParameters->GetSignal("TtotOn");
17094
17095 Double_t Fluence=-1;
17096
17097 Int_t n=TMath::Nint(nsig);
17098
17099 if (n<1 || Ton<=0) return -1;
17100
17101 Int_t nen=fBurstOnAeff.GetN();
17102
17103 if (n>nen) n=nen; // Only stored values should be used
17104
17105 // Take the Fluence sum of the "nsig" values ordered by increasing angular separation.
17106 // The assumption is that the closest tracks represent signal tracks.
17107 // Also an incoming Fluence vs. E histogram will be created for each "signal track".
17108 Double_t E=0;
17109 Double_t Stot=0;
17110 TString nameS,titleS,nameF,titleF,nameE2F,titleE2F;
17111 nameS.Form("h%-sFluence",str.Data());
17112 titleS.Form("Stacked incoming signal Fluence for Bayesian %s rate;Event energy [GeV];dN/dE [GeV^{-1} cm^{-2}]",str.Data());
17113 nameF.Form("h%-sFlux",str.Data());
17114 titleF.Form("Incoming signal Flux for a steady Bayesian %s rate;Event energy [GeV];dN/dE [GeV^{-1} cm^{-2} s^{-1}]",str.Data());
17115 nameE2F.Form("h%-sE2Flux",str.Data());
17116 titleE2F.Form("E-Scaled incoming signal Flux for a steady Bayesian %s rate;Event energy [GeV];E^{2}dN/dE [GeV cm^{-2} s^{-1}]",str.Data());
17117 TH1F* hS=0;
17118 TH1F* hF=0;
17119 TH1F* hE2F=0;
17120
17121 if (str!="-")
17122 {
17123 hS=(TH1F*)fBurstHistos.FindObject(nameS);
17124 hF=(TH1F*)fBurstHistos.FindObject(nameF);
17125 hE2F=(TH1F*)fBurstHistos.FindObject(nameE2F);
17126 if (hS)
17127 {
17128 delete hS;
17129 hS=new TH1F(nameS,titleS,100,0,-1);
17130 delete hF;
17131 hF=new TH1F(nameF,titleF,100,0,-1);
17132 delete hE2F;
17133 hE2F=new TH1F(nameE2F,titleE2F,100,0,-1);
17134 }
17135 else
17136 {
17137 hS=new TH1F(nameS,titleS,100,0,-1);
17138 fBurstHistos.Add(hS);
17139 hF=new TH1F(nameF,titleF,100,0,-1);
17140 fBurstHistos.Add(hF);
17141 hE2F=new TH1F(nameE2F,titleE2F,100,0,-1);
17142 fBurstHistos.Add(hE2F);
17143 }
17144
17145 hS->Sumw2();
17146 hF->Sumw2();
17147 hE2F->Sumw2();
17148 }
17149
17150 for (Int_t i=1; i<=n; i++)
17151 {
17152 Fluence=fBurstOnAeff.GetEntry(i,"Fluence",1,"dang");
17153 E=fBurstOnAeff.GetEntry(i,"E",1,"dang");
17154 Stot+=Fluence;
17155 if (Fluence>0 && hS)
17156 {
17157 hS->Fill(E,Fluence);
17158 hF->Fill(E,Fluence/Ton);
17159 hE2F->Fill(E,pow(E,2)*Fluence/Ton);
17160 }
17161 }
17162
17163 // Convert the histogram data into dN/dE
17164 if (hS)
17165 {
17166 // Flush the storage buffers to actually fill the histograms
17167 hS->BufferEmpty(1);
17168 hF->BufferEmpty(1);
17169 hE2F->BufferEmpty(1);
17170 Float_t binwidth=hS->GetBinWidth(1);
17171 if (binwidth>0)
17172 {
17173 hS->Scale(1./binwidth);
17174 hF->Scale(1./binwidth);
17175 hE2F->Scale(1./binwidth);
17176 }
17177 }
17178
17179 return Stot;
17180}
17181
17182void NcAstrolab::ListBurstSignalStats(Double_t Rate,Int_t mode,TString str)
17183{
17202
17203 // The number of on-source patches
17204 Int_t fNgrbs=GetNsignals(0);
17205
17206 // The integrated on-source exposure time in seconds
17207 Float_t Ton=fBurstParameters->GetSignal("TtotOn");
17208 Float_t TwinOn=Ton/float(fNgrbs); // The average time window in seconds
17209
17210 // The (stacked) on-source solid angle that was probed
17211 Float_t fSolidangleOn=fBurstParameters->GetSignal("SolidangleOn");
17212 Float_t fAvSolidangleOn=fBurstParameters->GetSignal("AvSolidangleOn");
17213
17214 // The area covered c.q. overlooked by the detector sensors
17215 Float_t fSensarea=fBurstParameters->GetSignal("Sensarea");
17216 fSensarea*=1e4; // Convert to cm^2
17217
17218 // The total accumulated on-source values
17219 Float_t Time=Ton;
17220 Float_t Omega=fSolidangleOn;
17221
17222 // Use the (averaged) observation values per patch
17223 if (abs(mode)==2)
17224 {
17225 Time=TwinOn;
17226 Omega=fAvSolidangleOn;
17227 }
17228
17229 // Determine the corresponding expected number of events
17230 Float_t Nevt=Rate*Time;
17231
17232 Float_t Fluence=-1;
17233 if (mode==1)
17234 {
17235 Fluence=GetBurstTotalFluence(Nevt,str);
17236 }
17237 if (mode==2)
17238 {
17239 Fluence=GetBurstTotalFluence(Nevt*float(fNgrbs),"-");
17240 Fluence=Fluence/float(fNgrbs);
17241 }
17242
17243 TString type="signal";
17244 if (mode<0) type="background";
17245
17246 printf(" Expected recorded number of %-s events : %-g",type.Data(),Nevt);
17247 if (Omega) printf(" --> %-g events/sr",Nevt/Omega);
17248 printf("\n");
17249 if (fSensarea>0)
17250 {
17251 printf(" Expected recorded %-s particle fluence : %-g cm^-2",type.Data(),Nevt/fSensarea);
17252 if (Omega) printf(" --> %-g cm^-2 sr^-1",Nevt/(fSensarea*Omega));
17253 printf("\n");
17254 printf(" Expected recorded %-s particle flux : %-g cm^-2 s^-1",type.Data(),Rate/fSensarea);
17255 if (Omega) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",Rate/(fSensarea*Omega));
17256 printf("\n");
17257 }
17258 if (Fluence>0)
17259 {
17260 printf(" Expected incoming %-s particle fluence : %-g cm^-2",type.Data(),Fluence);
17261 if (Omega) printf(" --> %-g cm^-2 sr^-1",Fluence/Omega);
17262 printf("\n");
17263 printf(" Expected incoming %-s particle flux : %-g cm^-2 s^-1",type.Data(),Fluence/Time);
17264 if (Omega) printf(" --> Intensity : %-g cm^-2 s^-1 sr^-1",Fluence/(Time*Omega));
17265 printf("\n");
17266 }
17267}
17268
17270{
17283
17284 Double_t sigma=0;
17285
17286 // The recorded (stacked) "on source" and "off source" number of events
17287 Double_t Non=fBurstOnMatch.GetN();
17288 Double_t Noff=fBurstOffMatch.GetN();
17289
17290 if (Non<=0 || Noff<=0)
17291 {
17292 printf(" \n *%-s::GetBurstLiMaSignificance* \n",ClassName());
17293 if (Non<=0) printf(" === No on source data available === \n");
17294 if (Noff<=0) printf(" === No off source data available === \n");
17295 return 0;
17296 }
17297
17298 // The (stacked) "on source" and "off source" solid angles that were probed
17299 Double_t fAvSolidangleOn=fBurstParameters->GetSignal("AvSolidangleOn");
17300 Double_t fAvSolidangleOff=fBurstParameters->GetSignal("AvSolidangleOff");
17301 Double_t Ra=-1;
17302 if (fAvSolidangleOff) Ra=fAvSolidangleOn/fAvSolidangleOff;
17303
17304 // The (stacked) "on source" and "off source" exposure times
17305 Double_t Ton=fBurstParameters->GetSignal("TtotOn");
17306 Double_t Toff=fBurstParameters->GetSignal("TtotOff");
17307
17308 NcMath m;
17309 sigma=m.LiMaSignificance(Non,Ton,Noff,Toff,Ra);
17310
17311 printf("\n *%-s::GetBurstLiMaSignificance* The Li-Ma signal significance is : %-g \n",ClassName(),sigma);
17312
17313 // Issue a warning in case variable angular cones based on actual track reco sigmas were used.
17314 // This can induce large variations in the on-source and off-source event counts
17315 Int_t fDatype=TMath::Nint(fBurstParameters->GetSignal("Datype"));
17316 Int_t fRecoangle=TMath::Nint(fBurstParameters->GetSignal("Recoangle"));
17317 Int_t fSumsigmas=TMath::Nint(fBurstParameters->GetSignal("Sumsigmas"));
17318
17319 if (fRecoangle && fSumsigmas && fDatype==2)
17320 {
17321 printf(" === Warning: Variable angular cones based on actual track reconstruction sigmas were used. \n");
17322 printf(" Large variations between the on-source and off-source background counts may be present. \n");
17323 }
17324
17325 return sigma;
17326}
17327
17328void NcAstrolab::GetBurstBayesianPsiStatistics(TString type,Double_t nr,Int_t ncut,Int_t ndt,Bool_t zcor,Int_t freq)
17329{
17399
17400 NcMath math;
17401
17402 TString text="none";
17403 if (type=="time") text="arrival time";
17404 if (type=="BBtime") text="Bayesian Block event rate";
17405 if (type=="BBrat") text="normalized On-source/Off-source Bayesian Block event rate ratio";
17406 if (type=="angle") text="opening angle";
17407 if (type=="cosa") text="cos(opening angle)";
17408 if (type=="dt") text="arrival time interval";
17409
17410 if (zcor)
17411 {
17412 text.ReplaceAll("arrival time","redshift corrected arrival time");
17413 text.ReplaceAll("event rate","redshift corrected event rate");
17414 }
17415
17416 cout << endl;
17417 if (text=="none")
17418 {
17419 cout << " *" << ClassName() << "::GetBurstBayesianPsiStatistics* Unknown statistics type : " << type << endl;
17420 return;
17421 }
17422 else
17423 {
17424 cout << " *" << ClassName() << "::GetBurstBayesianPsiStatistics* Analysis of " << text << " statistics" << endl;
17425 }
17426
17427 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
17428 TString tu="days";
17429 if (fTunits==1) tu="hours";
17430 if (fTunits==2) tu="sec";
17431 if (fTunits==3) tu="ns";
17432 if (fTunits==4) tu="ps";
17433
17434 TH1* tot=0;
17435 TH1* bkg=0;
17436 TH1* rat=0;
17437
17438 Double_t psitot=-1, psibkg=-1, psirat=-1;
17439 Float_t psidif=0;
17440 Float_t psimintot=-1, psimaxtot=-1, psifractot=0;
17441 Float_t psiminbkg=-1, psimaxbkg=-1, psifracbkg=0;
17442 Float_t psiminrat=-1, psimaxrat=-1, psifracrat=0;
17443 Double_t nrxtot=-1, nrxbkg=-1, nrxrat=-1;
17444 Double_t pvaluetot=-1, pvaluebkg=-1, pvaluerat=-1;
17445
17446 TH1F* hPsiOn=0;
17447 TH1F* hPsiOff=0;
17448 TH1F* hPsiRat=0;
17449 TH1F* rtot=0;
17450 TH1F* rbkg=0;
17451 TH1F* rrat=0;
17452
17454 // Arrival time histo Bayesian statistics //
17456 if (type=="time")
17457 {
17458 if (!zcor) // Plain observed arrival times
17459 {
17460 tot=(TH1*)fBurstHistos.FindObject("hOnt");
17461 bkg=(TH1*)fBurstHistos.FindObject("hOfft");
17462 }
17463 else // Redshift corrected arrival times
17464 {
17465 tot=(TH1*)fBurstHistos.FindObject("hOnZt");
17466 bkg=(TH1*)fBurstHistos.FindObject("hOffZt");
17467 }
17468
17469 if (!tot) printf(" === No on source data available === \n");
17470 if (!bkg) printf(" === No off source data available === \n");
17471
17472 if (!tot && !bkg) return;
17473
17474 if (tot) psitot=math.PsiValue(tot,0,0,freq);
17475 if (bkg) psibkg=math.PsiValue(bkg,0,0,freq);
17476 psidif=psitot-psibkg;
17477
17478 // Extreme Psi values for a pure background hypothesis of the recorded arrival time entries
17479 if (tot)
17480 {
17481 psimintot=math.PsiExtreme(tot,0,0,-2);
17482 if (psitot<psimintot) psimintot=psitot;
17483 psimaxtot=math.PsiExtreme(tot,0,0,-1);
17484 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
17485 }
17486 if (bkg)
17487 {
17488 psiminbkg=math.PsiExtreme(bkg,0,0,-2);
17489 if (psibkg<psiminbkg) psiminbkg=psibkg;
17490 psimaxbkg=math.PsiExtreme(bkg,0,0,-1);
17491 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
17492 }
17493
17494 // P-value determination
17495 if (nr>=0)
17496 {
17497 if (!zcor) // Plain observed arrival times
17498 {
17499 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnt");
17500 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOfft");
17501 }
17502 else // Redshift corrected arrival times
17503 {
17504 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnZt");
17505 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffZt");
17506 }
17507
17508 if (hPsiOn)
17509 {
17510 rtot=(TH1F*)hPsiOn->Clone();
17511 rtot->Reset();
17512 }
17513 else
17514 {
17515 if (tot)
17516 {
17517 if (!zcor) rtot=new TH1F("hPsiOnt","Psi distr. for bkg hypothesis of on-source arrival time data",100,psimintot-1.,psimaxtot+1.);
17518 if (zcor) rtot=new TH1F("hPsiOnZt","Psi distr. for bkg hypothesis of redshift corrected on-source arrival time data",100,psimintot-1.,psimaxtot+1.);
17519 }
17520 }
17521
17522 if (hPsiOff)
17523 {
17524 rbkg=(TH1F*)hPsiOff->Clone();
17525 rbkg->Reset();
17526 }
17527 else
17528 {
17529 if (bkg)
17530 {
17531 if (!zcor) rbkg=new TH1F("hPsiOfft","Psi distr. for bkg hypothesis of off-source arrival time data",100,psiminbkg-1.,psimaxbkg+1.);
17532 if (zcor) rbkg=new TH1F("hPsiOffZt","Psi distr. for bkg hypothesis of redshift corrected off-source arrival time data",100,psiminbkg-1.,psimaxbkg+1.);
17533 }
17534 }
17535
17536 if (tot)
17537 {
17538 pvaluetot=math.PsiPvalue(-1,nr,tot,0,0,freq,0,rtot,ncut,&nrxtot);
17539 fBurstHistos.Add(rtot);
17540 }
17541 if (bkg)
17542 {
17543 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,0,freq,0,rbkg,ncut,&nrxbkg);
17544 fBurstHistos.Add(rbkg);
17545 }
17546
17547 cout << " The following randomised Psi histograms have been generated :" << endl;
17548 if (rtot) cout << " ... " << rtot->GetName() << " : " << rtot->GetTitle() << endl;
17549 if (rbkg) cout << " ... " << rbkg->GetName() << " : " << rbkg->GetTitle() << endl;
17550 }
17551 }
17552
17554 // Event rate histo Bayesian statistics //
17556 if (type=="BBtime")
17557 {
17558 if (!zcor) // Plain observed arrival times
17559 {
17560 tot=(TH1*)fBurstHistos.FindObject("hOnBBt");
17561 bkg=(TH1*)fBurstHistos.FindObject("hOffBBt");
17562 }
17563 else // Redshift corrected arrival times
17564 {
17565 tot=(TH1*)fBurstHistos.FindObject("hOnBBzt");
17566 bkg=(TH1*)fBurstHistos.FindObject("hOffBBzt");
17567 }
17568
17569 if (!tot) printf(" === No on source data available === \n");
17570 if (!bkg) printf(" === No off source data available === \n");
17571
17572 if (!tot && !bkg) return;
17573
17574 // Temporarily offset the bin contents so that the lowest bin content is 1 for the psi analysis
17575 if (tot)
17576 {
17577 for (Int_t i=1; i<=tot->GetNbinsX(); i++)
17578 {
17579 tot->AddBinContent(i,1);
17580 }
17581 }
17582
17583 if (bkg)
17584 {
17585 for (Int_t i=1; i<=bkg->GetNbinsX(); i++)
17586 {
17587 bkg->AddBinContent(i,1);
17588 }
17589 }
17590
17591 if (tot) psitot=math.PsiValue(tot,0,0,freq);
17592 if (bkg) psibkg=math.PsiValue(bkg,0,0,freq);
17593 psidif=psitot-psibkg;
17594
17595 // Extreme Psi values for a pure background hypothesis of the recorded arrival time entries
17596 if (tot)
17597 {
17598 psimintot=math.PsiExtreme(tot,0,0,-2);
17599 if (psitot<psimintot) psimintot=psitot;
17600 psimaxtot=math.PsiExtreme(tot,0,0,-1);
17601 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
17602 }
17603 if (bkg)
17604 {
17605 psiminbkg=math.PsiExtreme(bkg,0,0,-2);
17606 if (psibkg<psiminbkg) psiminbkg=psibkg;
17607 psimaxbkg=math.PsiExtreme(bkg,0,0,-1);
17608 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
17609 }
17610
17611 // P-value determination
17612 if (nr>=0)
17613 {
17614 if (!zcor) // Plain observed arrival times
17615 {
17616 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnBBt");
17617 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffBBt");
17618 }
17619 else // Redshift corrected arrival times
17620 {
17621 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnBBzt");
17622 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffBBzt");
17623 }
17624
17625 if (hPsiOn)
17626 {
17627 rtot=(TH1F*)hPsiOn->Clone();
17628 rtot->Reset();
17629 }
17630 else
17631 {
17632 if (tot)
17633 {
17634 if (!zcor) rtot=new TH1F("hPsiOnBBt","Psi distr. for bkg hypothesis of on-source event rate Bayesian Block data",100,psimintot-1.,psimaxtot+1.);
17635 if (zcor) rtot=new TH1F("hPsiOnBBzt","Psi distr. for bkg hypothesis of redshift corrected on-source event rate Bayesian Block data",100,psimintot-1.,psimaxtot+1.);
17636 }
17637 }
17638
17639 if (hPsiOff)
17640 {
17641 rbkg=(TH1F*)hPsiOff->Clone();
17642 rbkg->Reset();
17643 }
17644 else
17645 {
17646 if (bkg)
17647 {
17648 if (!zcor) rbkg=new TH1F("hPsiOffBBt","Psi distr. for bkg hypothesis of off-source event rate Bayesian Block data",100,psiminbkg-1.,psimaxbkg+1.);
17649 if (zcor) rbkg=new TH1F("hPsiOffBBzt","Psi distr. for bkg hypothesis of redshift corrected off-source event rate Bayesian Block data",100,psiminbkg-1.,psimaxbkg+1.);
17650 }
17651 }
17652
17653 if (tot)
17654 {
17655 pvaluetot=math.PsiPvalue(-1,nr,tot,0,0,freq,0,rtot,ncut,&nrxtot);
17656 fBurstHistos.Add(rtot);
17657 }
17658 if (bkg)
17659 {
17660 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,0,freq,0,rbkg,ncut,&nrxbkg);
17661 fBurstHistos.Add(rbkg);
17662 }
17663
17664 cout << " The following randomised Psi histograms have been generated :" << endl;
17665 if (rtot) cout << " ... " << rtot->GetName() << " : " << rtot->GetTitle() << endl;
17666 if (rbkg) cout << " ... " << rbkg->GetName() << " : " << rbkg->GetTitle() << endl;
17667 }
17668
17669 // Restore the original histogram data
17670 if (tot)
17671 {
17672 for (Int_t i=1; i<=tot->GetNbinsX(); i++)
17673 {
17674 tot->AddBinContent(i,-1);
17675 }
17676 }
17677 if (bkg)
17678 {
17679 for (Int_t i=1; i<=bkg->GetNbinsX(); i++)
17680 {
17681 bkg->AddBinContent(i,-1);
17682 }
17683 }
17684 }
17685
17687 // On-source/Off-source event rate ratio histo Bayesian statistics //
17689 if (type=="BBrat")
17690 {
17691 if (!zcor) // Plain observed arrival times
17692 {
17693 rat=(TH1*)fBurstHistos.FindObject("hRatUBBt");
17694 }
17695 else // Redshift corrected arrival times
17696 {
17697 rat=(TH1*)fBurstHistos.FindObject("hRatUBBzt");
17698 }
17699
17700 if (!rat)
17701 {
17702 printf(" === No data available === \n");
17703 return;
17704 }
17705
17706 psirat=math.PsiValue(rat,0,0,freq);
17707 psidif=psitot-psibkg;
17708
17709 // Extreme Psi values for a pure background hypothesis of the recorded arrival time entries
17710 psiminrat=math.PsiExtreme(rat,0,0,-2);
17711 if (psirat<psiminrat) psiminrat=psirat;
17712 psimaxrat=math.PsiExtreme(rat,0,0,-1);
17713 if (psimaxrat>psiminrat) psifracrat=(psimaxrat-psirat)/(psimaxrat-psiminrat);
17714
17715 // P-value determination
17716 if (nr>=0)
17717 {
17718 if (!zcor) // Plain observed arrival times
17719 {
17720 hPsiRat=(TH1F*)fBurstHistos.FindObject("hPsiRatUBBt");
17721 }
17722 else // Redshift corrected arrival times
17723 {
17724 hPsiRat=(TH1F*)fBurstHistos.FindObject("hPsiRatUBBzt");
17725 }
17726
17727 if (hPsiRat)
17728 {
17729 rrat=(TH1F*)hPsiRat->Clone();
17730 rrat->Reset();
17731 }
17732 else
17733 {
17734 if (!zcor) rrat=new TH1F("hPsiRatUBBt","Psi distr. for bkg hypothesis of on/off source event rate Bayesian Block data",100,psiminrat-1.,psimaxrat+1.);
17735 if (zcor) rrat=new TH1F("hPsiRatUBBzt","Psi distr. for bkg hypothesis of redshift corrected on/off source event rate Bayesian Block data",100,psiminrat-1.,psimaxrat+1.);
17736 }
17737
17738 pvaluerat=math.PsiPvalue(-1,nr,rat,0,0,freq,0,rrat,ncut,&nrxrat);
17739 fBurstHistos.Add(rrat);
17740
17741 cout << " The following randomised Psi histograms have been generated :" << endl;
17742 if (rrat) cout << " ... " << rrat->GetName() << " : " << rrat->GetTitle() << endl;
17743 }
17744 }
17745
17747 // Opening angle histo Bayesian statistics //
17749 if (type=="angle")
17750 {
17751 tot=(TH1*)fBurstHistos.FindObject("hOna");
17752 bkg=(TH1*)fBurstHistos.FindObject("hOffa");
17753
17754 if (!tot) printf(" === No on source data available === \n");
17755 if (!bkg) printf(" === No off source data available === \n");
17756
17757 if (!tot && !bkg) return;
17758
17759 TF1 pdfa("pdfa","sin(x*acos(-1.)/180.)");
17760 if (tot) psitot=math.PsiValue(tot,0,&pdfa,freq);
17761 if (bkg) psibkg=math.PsiValue(bkg,0,&pdfa,freq);
17762 psidif=psitot-psibkg;
17763
17764 // Extreme Psi values for a pure background hypothesis of the recorded opening angle entries
17765 if (tot)
17766 {
17767 psimintot=math.PsiExtreme(tot,0,&pdfa,-2);
17768 if (psitot<psimintot) psimintot=psitot;
17769 psimaxtot=math.PsiExtreme(tot,0,&pdfa,-1);
17770 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
17771 }
17772 if (bkg)
17773 {
17774 psiminbkg=math.PsiExtreme(bkg,0,&pdfa,-2);
17775 if (psibkg<psiminbkg) psiminbkg=psibkg;
17776 psimaxbkg=math.PsiExtreme(bkg,0,&pdfa,-1);
17777 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
17778 }
17779
17780 // P-value determination
17781 if (nr>=0)
17782 {
17783 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOna");
17784 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffa");
17785
17786 if (hPsiOn)
17787 {
17788 rtot=(TH1F*)hPsiOn->Clone();
17789 rtot->Reset();
17790 }
17791 else
17792 {
17793 if (tot) rtot=new TH1F("hPsiOna","Psi distr. for bkg hypothesis of on-source opening angle data",100,psimintot-1.,psimaxtot+1.);
17794 }
17795
17796 if (hPsiOff)
17797 {
17798 rbkg=(TH1F*)hPsiOff->Clone();
17799 rbkg->Reset();
17800 }
17801 else
17802 {
17803 if (bkg) rbkg=new TH1F("hPsiOffa","Psi distr. for bkg hypothesis of off-source opening angle data",100,psiminbkg-1.,psimaxbkg+1.);
17804 }
17805
17806 if (tot)
17807 {
17808 pvaluetot=math.PsiPvalue(-1,nr,tot,0,&pdfa,freq,0,rtot,ncut,&nrxtot);
17809 fBurstHistos.Add(rtot);
17810 }
17811 if (bkg)
17812 {
17813 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,&pdfa,freq,0,rbkg,ncut,&nrxbkg);
17814 fBurstHistos.Add(rbkg);
17815 }
17816
17817 cout << " The following randomised Psi histograms have been generated :" << endl;
17818 if (rtot) cout << " ... " << rtot->GetName() << " : " << rtot->GetTitle() << endl;
17819 if (rbkg) cout << " ... " << rbkg->GetName() << " : " << rbkg->GetTitle() << endl;
17820 }
17821 }
17822
17824 // Cosine of opening angle histo Bayesian statistics //
17826 if (type=="cosa")
17827 {
17828 tot=(TH1*)fBurstHistos.FindObject("hOnCosa");
17829 bkg=(TH1*)fBurstHistos.FindObject("hOffCosa");
17830
17831 if (!tot) printf(" === No on source data available === \n");
17832 if (!bkg) printf(" === No off source data available === \n");
17833
17834 if (!tot && !bkg) return;
17835
17836 if (tot) psitot=math.PsiValue(tot,0,0,freq);
17837 if (bkg) psibkg=math.PsiValue(bkg,0,0,freq);
17838 psidif=psitot-psibkg;
17839
17840 // Extreme Psi values for a pure background hypothesis of the recorded cos(opening angle) entries
17841 if (tot)
17842 {
17843 psimintot=math.PsiExtreme(tot,0,0,-2);
17844 if (psitot<psimintot) psimintot=psitot;
17845 psimaxtot=math.PsiExtreme(tot,0,0,-1);
17846 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
17847 }
17848 if (bkg)
17849 {
17850 psiminbkg=math.PsiExtreme(bkg,0,0,-2);
17851 if (psibkg<psiminbkg) psiminbkg=psibkg;
17852 psimaxbkg=math.PsiExtreme(bkg,0,0,-1);
17853 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
17854 }
17855
17856 // P-value determination
17857 if (nr>=0)
17858 {
17859 hPsiOn=(TH1F*)fBurstHistos.FindObject("hPsiOnCosa");
17860 hPsiOff=(TH1F*)fBurstHistos.FindObject("hPsiOffCosa");
17861
17862 if (hPsiOn)
17863 {
17864 rtot=(TH1F*)hPsiOn->Clone();
17865 rtot->Reset();
17866 }
17867 else
17868 {
17869 if (tot) rtot=new TH1F("hPsiOnCosa","Psi distr. for bkg hypothesis of on-source cos(opening angle) data",100,psimintot-1.,psimaxtot+1.);
17870 }
17871
17872 if (hPsiOff)
17873 {
17874 rbkg=(TH1F*)hPsiOff->Clone();
17875 rbkg->Reset();
17876 }
17877 else
17878 {
17879 if (bkg) rbkg=new TH1F("hPsiOffCosa","Psi distr. for bkg hypothesis of off-source cos(opening angle) data",100,psiminbkg-1.,psimaxbkg+1.);
17880 }
17881
17882 if (tot)
17883 {
17884 pvaluetot=math.PsiPvalue(-1,nr,tot,0,0,freq,0,rtot,ncut,&nrxtot);
17885 fBurstHistos.Add(rtot);
17886 }
17887 if (bkg)
17888 {
17889 pvaluebkg=math.PsiPvalue(-1,nr,bkg,0,0,freq,0,rbkg,ncut,&nrxbkg);
17890 fBurstHistos.Add(rbkg);
17891 }
17892
17893 cout << " The following randomised Psi histograms have been generated :" << endl;
17894 if (rtot) cout << " ... " << rtot->GetName() << " : " << rtot->GetTitle() << endl;
17895 if (rbkg) cout << " ... " << rbkg->GetName() << " : " << rbkg->GetTitle() << endl;
17896 }
17897 }
17898
17900 // Arrival time interval Bayesian statistics //
17902 if (type=="dt")
17903 {
17904 TH1F hOndt;
17905 TH1F hOffdt;
17906 TF1 pdfdttot;
17907 TF1 pdfdtbkg;
17908
17909 GetBurstDtDistributions(ndt,hOndt,pdfdttot,hOffdt,pdfdtbkg,zcor);
17910
17911 Int_t ntot=hOndt.GetEntries();
17912 Int_t nbkg=hOffdt.GetEntries();
17913
17914 if (!ntot) printf(" === No on source data available === \n");
17915 if (!nbkg) printf(" === No off source data available === \n");
17916
17917 if (!ntot && !nbkg) return;
17918
17919 if (ntot) psitot=math.PsiValue(&hOndt,0,&pdfdttot,freq);
17920 if (nbkg) psibkg=math.PsiValue(&hOffdt,0,&pdfdtbkg,freq);
17921 psidif=psitot-psibkg;
17922
17923 if (ntot)
17924 {
17925 psimintot=math.PsiExtreme(&hOndt,0,&pdfdttot,-2);
17926 if (psitot<psimintot) psimintot=psitot;
17927 psimaxtot=math.PsiExtreme(&hOndt,0,&pdfdttot,-1);
17928 if (psimaxtot>psimintot) psifractot=(psimaxtot-psitot)/(psimaxtot-psimintot);
17929 }
17930 if (nbkg)
17931 {
17932 psiminbkg=math.PsiExtreme(&hOffdt,0,&pdfdtbkg,-2);
17933 if (psibkg<psiminbkg) psiminbkg=psibkg;
17934 psimaxbkg=math.PsiExtreme(&hOffdt,0,&pdfdtbkg,-1);
17935 if (psimaxbkg>psiminbkg) psifracbkg=(psimaxbkg-psibkg)/(psimaxbkg-psiminbkg);
17936 }
17937
17938 // P-value determination
17939 if (nr>=0)
17940 {
17941 TString nametot;
17942 TString namebkg;
17943 if (!zcor)
17944 {
17945 nametot.Form("hPsiOndt%-i",ndt);
17946 namebkg.Form("hPsiOffdt%-i",ndt);
17947 }
17948 else
17949 {
17950 nametot.Form("hPsiOnZdt%-i",ndt);
17951 namebkg.Form("hPsiOffZdt%-i",ndt);
17952 }
17953
17954 TH1F* hPsiOn=(TH1F*)fBurstHistos.FindObject(nametot);
17955 TH1F* hPsiOff=(TH1F*)fBurstHistos.FindObject(namebkg);
17956
17957 TString title;
17958 if (hPsiOn)
17959 {
17960 rtot=(TH1F*)hPsiOn->Clone();
17961 rtot->Reset();
17962 }
17963 else
17964 {
17965 if (!zcor) title.Form("Psi distr. for bkg hypothesis of on-source dt data for n=%-i",ndt);
17966 if (zcor) title.Form("Psi distr. for bkg hypothesis of redshift corrected on-source dt data for n=%-i",ndt);
17967 if (ntot) rtot=new TH1F(nametot,title,100,psimintot-1.,psimaxtot+1.);
17968 }
17969
17970 if (hPsiOff)
17971 {
17972 rbkg=(TH1F*)hPsiOff->Clone();
17973 rbkg->Reset();
17974 }
17975 else
17976 {
17977 if (!zcor) title.Form("Psi distr. for bkg hypothesis of off-source dt data for n=%-i",ndt);
17978 if (zcor) title.Form("Psi distr. for bkg hypothesis of redshift corrected off-source dt data for n=%-i",ndt);
17979 if (nbkg) rbkg=new TH1F(namebkg,title,100,psiminbkg-1.,psimaxbkg+1.);
17980 }
17981
17982 if (ntot)
17983 {
17984 pvaluetot=math.PsiPvalue(-1,nr,&hOndt,0,&pdfdttot,freq,0,rtot,ncut,&nrxtot);
17985 fBurstHistos.Add(rtot);
17986 }
17987 if (nbkg)
17988 {
17989 pvaluebkg=math.PsiPvalue(-1,nr,&hOffdt,0,&pdfdtbkg,freq,0,rbkg,ncut,&nrxbkg);
17990 fBurstHistos.Add(rbkg);
17991 }
17992
17993 cout << " The following randomised Psi histograms have been (re)generated :" << endl;
17994 if (rtot) cout << " ... " << rtot->GetName() << " : " << rtot->GetTitle() << endl;
17995 if (rbkg) cout << " ... " << rbkg->GetName() << " : " << rbkg->GetTitle() << endl;
17996 }
17997 }
17998
17999 // Listing of the statistics results
18000 cout << " *** Observed Psi values (in dB) for the hypothesis of no burst signal ***" << endl;
18001 if (psitot>=0) cout << " For the on-source stacked patches : psi = " << psitot << endl;
18002 if (psibkg>=0) cout << " For the off-source stacked patches : psi = " << psibkg << endl;
18003 if (psitot>=0 && psibkg>=0) cout << " --> Difference between observed on-source and off-source psi values : " << psidif << endl;
18004 if (psirat>=0) cout << " For the on/off source event rate Bayesian Blocks : psi = " << psirat << endl;
18005 cout << " *** Extreme Psi values for the case of pure background ***" << endl;
18006 if (psimintot>=0) cout << " For on-source psimin : " << psimintot << " psimax : " << psimaxtot;
18007 if (psifractot>0) printf(" (psimax-psi)/range : %-g",psifractot);
18008 if (psimintot>=0 || psifractot>0) printf("\n");
18009 if (psiminbkg>=0) cout << " For off-source psimin : " << psiminbkg << " psimax : " << psimaxbkg;
18010 if (psifracbkg>0) printf(" (psimax-psi)/range : %-g",psifracbkg);
18011 if (psiminbkg>=0 || psifracbkg>0) printf("\n");
18012 if (psiminrat>=0) cout << " For on/off source event rate Bayesian Blocks psimin : " << psiminrat << " psimax : " << psimaxrat;
18013 if (psifracrat>0) printf(" (psimax-psi)/range : %-g",psifracrat);
18014 if (psiminrat>=0 || psifracrat>0) printf("\n");
18015
18016 if (nr>=0)
18017 {
18018 cout << " *** P-values of the observed on-source and off-source psi values ***" << endl;
18019 if (nrxtot>0) cout << " For the on-source stacked patches : P-value = " << pvaluetot << " Used number of randomisations : " << nrxtot << endl;
18020 if (nrxbkg>0) cout << " For the off-source stacked patches : P-value = " << pvaluebkg << " Used number of randomisations : " << nrxbkg << endl;
18021 if (nrxrat>0) cout << " For the on/off source event rate Bayesian Blocks : P-value = " << pvaluerat << " Used number of randomisations : " << nrxrat << endl;
18022 }
18023}
18024
18025void NcAstrolab::GetBurstChi2Statistics(TString type,Int_t ndt,Bool_t zcor)
18026{
18061
18062 NcMath math;
18063
18064 TString text="none";
18065 if (type=="time") text="arrival time";
18066 if (type=="BBtime") text="Bayesian Block event rate";
18067 if (type=="BBrat") text="normalized On-source/Off-source Bayesian Block event rate ratio";
18068 if (type=="angle") text="opening angle";
18069 if (type=="cosa") text="cos(opening angle)";
18070 if (type=="dt") text="arrival time interval";
18071
18072 if (zcor)
18073 {
18074 text.ReplaceAll("arrival time","redshift corrected arrival time");
18075 text.ReplaceAll("event rate","redshift corrected event rate");
18076 }
18077
18078 cout << endl;
18079 if (text=="none")
18080 {
18081 cout << " *" << ClassName() << "::GetBurstChi2Statistics* Unknown statistics type : " << type << endl;
18082 return;
18083 }
18084 else
18085 {
18086 cout << " *" << ClassName() << "::GetBurstChi2Statistics* Analysis of " << text << " statistics" << endl;
18087 }
18088
18089 TH1* tot=0;
18090 TH1* bkg=0;
18091 TH1* rat=0;
18092
18093 Int_t ndftot=0;
18094 Int_t ndfbkg=0;
18095 Int_t ndfrat=0;
18096 Float_t chitot=0;
18097 Float_t chibkg=0;
18098 Float_t chirat=0;
18099
18101 // Arrival time histo Chi-squared statistics //
18103 if (type=="time")
18104 {
18105 if (!zcor)
18106 {
18107 tot=(TH1*)fBurstHistos.FindObject("hOnt");
18108 bkg=(TH1*)fBurstHistos.FindObject("hOfft");
18109 }
18110 else
18111 {
18112 tot=(TH1*)fBurstHistos.FindObject("hOnZt");
18113 bkg=(TH1*)fBurstHistos.FindObject("hOffZt");
18114 }
18115
18116 if (!tot) printf(" === No on source data available === \n");
18117 if (!bkg) printf(" === No off source data available === \n");
18118
18119 if (!tot && !bkg) return;
18120
18121 if (tot) chitot=math.Chi2Value(tot,0,0,&ndftot);
18122 if (bkg) chibkg=math.Chi2Value(bkg,0,0,&ndfbkg);
18123 }
18124
18126 // Event rate histo Chi-squared statistics //
18128 if (type=="BBtime")
18129 {
18130 if (!zcor)
18131 {
18132 tot=(TH1*)fBurstHistos.FindObject("hOnBBt");
18133 bkg=(TH1*)fBurstHistos.FindObject("hOffBBt");
18134 }
18135 else
18136 {
18137 tot=(TH1*)fBurstHistos.FindObject("hOnBBzt");
18138 bkg=(TH1*)fBurstHistos.FindObject("hOffBBzt");
18139 }
18140
18141 if (!tot) printf(" === No on source data available === \n");
18142 if (!bkg) printf(" === No off source data available === \n");
18143
18144 if (!tot && !bkg) return;
18145
18146 if (tot) chitot=math.Chi2Value(tot,0,0,&ndftot);
18147 if (bkg) chibkg=math.Chi2Value(bkg,0,0,&ndfbkg);
18148 }
18149
18151 // On-source/Off-source event rate ratio histo Chi-squared statistics //
18153 if (type=="BBrat")
18154 {
18155 if (!zcor)
18156 {
18157 rat=(TH1*)fBurstHistos.FindObject("hRatUBBt");
18158 }
18159 else
18160 {
18161 rat=(TH1*)fBurstHistos.FindObject("hRatUBBzt");
18162 }
18163
18164 if (!rat)
18165 {
18166 printf(" === No data available === \n");
18167 return;
18168 }
18169
18170 chirat=math.Chi2Value(rat,0,0,&ndfrat);
18171 }
18172
18174 // Opening angle histo Chi-squared statistics //
18176 if (type=="angle")
18177 {
18178 tot=(TH1*)fBurstHistos.FindObject("hOna");
18179 bkg=(TH1*)fBurstHistos.FindObject("hOffa");
18180
18181 if (!tot) printf(" === No on source data available === \n");
18182 if (!bkg) printf(" === No off source data available === \n");
18183
18184 if (!tot && !bkg) return;
18185
18186 TF1 pdf("pdf","sin(x*acos(-1.)/180.)");
18187 if (tot) chitot=math.Chi2Value(tot,0,&pdf,&ndftot);
18188 if (bkg) chibkg=math.Chi2Value(bkg,0,&pdf,&ndfbkg);
18189 }
18190
18192 // Cosine of opening angle histo Chi-squared statistics //
18194 if (type=="cosa")
18195 {
18196 tot=(TH1*)fBurstHistos.FindObject("hOnCosa");
18197 bkg=(TH1*)fBurstHistos.FindObject("hOffCosa");
18198
18199 if (!tot) printf(" === No on source data available === \n");
18200 if (!bkg) printf(" === No off source data available === \n");
18201
18202 if (!tot && !bkg) return;
18203
18204 if (tot) chitot=math.Chi2Value(tot,0,0,&ndftot);
18205 if (bkg) chibkg=math.Chi2Value(bkg,0,0,&ndfbkg);
18206 }
18207
18209 // Arrival time interval Chi-squared statistics //
18211 if (type=="dt")
18212 {
18213 TH1F hOndt;
18214 TH1F hOffdt;
18215 TF1 pdfdttot;
18216 TF1 pdfdtbkg;
18217
18218 GetBurstDtDistributions(ndt,hOndt,pdfdttot,hOffdt,pdfdtbkg,zcor);
18219
18220 Int_t ntot=hOndt.GetEntries();
18221 Int_t nbkg=hOffdt.GetEntries();
18222
18223 if (!ntot) printf(" === No on source data available === \n");
18224 if (!nbkg) printf(" === No off source data available === \n");
18225
18226 if (!ntot && !nbkg) return;
18227
18228 if (ntot) chitot=math.Chi2Value(&hOndt,0,&pdfdttot,&ndftot);
18229 if (nbkg) chibkg=math.Chi2Value(&hOffdt,0,&pdfdtbkg,&ndfbkg);
18230 }
18231
18232 // Listing of the statistics results
18233 Float_t chidif=chitot-chibkg;
18234 cout << " *** Observed Chi-squared values for the hypothesis of no burst signal ***" << endl;
18235 if (chitot>0) cout << " For the on-source stacked patches : chi2 = " << chitot << " ndf = " << ndftot << endl;
18236 if (chibkg>0) cout << " For the off-source stacked patches : chi2 = " << chibkg << " ndf = " << ndfbkg << endl;
18237 if (chitot>0 && chibkg>0) cout << " --> Difference between observed on-source and off-source chi2 values : " << chidif << endl;
18238 if (chirat>0) cout << " For the on/off source event rate Bayesian Blocks : chi2 = " << chirat << " ndf = " << ndfrat << endl;
18239
18240 Float_t ptot=-1;
18241 Float_t sigmatot=-1;
18242 Float_t pbkg=-1;
18243 Float_t sigmabkg=-1;
18244 Float_t prat=-1;
18245 Float_t sigmarat=-1;
18246
18247 if (chitot)
18248 {
18249 ptot=math.Chi2Pvalue(chitot,ndftot);
18250 sigmatot=math.Chi2Pvalue(chitot,ndftot,0,1);
18251 }
18252 if (chibkg)
18253 {
18254 pbkg=math.Chi2Pvalue(chibkg,ndfbkg);
18255 sigmabkg=math.Chi2Pvalue(chibkg,ndfbkg,0,1);
18256 }
18257 if (chirat)
18258 {
18259 prat=math.Chi2Pvalue(chirat,ndfrat);
18260 sigmarat=math.Chi2Pvalue(chirat,ndfrat,0,1);
18261 }
18262
18263 cout << " *** P-values of the observed on-source and off-source chi2 values ***" << endl;
18264 if (ptot>=0) cout << " For the on-source stacked patches : P-value = " << ptot << " (" << sigmatot << " sigma)" << endl;
18265 if (pbkg>=0) cout << " For the off-source stacked patches : P-value = " << pbkg << " (" << sigmabkg << " sigma)" << endl;
18266 if (prat>=0) cout << " For the on/off source event rate Bayesian Blocks : P-value = " << prat << " (" << sigmarat << " sigma)" << endl;
18267}
18268
18269void NcAstrolab::GetBurstDtDistributions(Int_t ndt,TH1F& hisdtOn,TF1& pdfdtOn,TH1F& hisdtOff,TF1& pdfdtOff,Bool_t zcor)
18270{
18289
18290
18291 hisdtOn.Reset();
18292 hisdtOff.Reset();
18293
18294 Int_t fTunits=TMath::Nint(fBurstParameters->GetSignal("Tunits"));
18295 TString tu="days";
18296 if (fTunits==1) tu="hours";
18297 if (fTunits==2) tu="sec";
18298 if (fTunits==3) tu="ns";
18299 if (fTunits==4) tu="ps";
18300
18301 Float_t fTfact=fBurstParameters->GetSignal("Tfact");
18302
18303 TString nametot;
18304 TString namebkg;
18305 TString varname;
18306
18307 // Create the automatically binned delta t histograms
18308 if (!zcor)
18309 {
18310 nametot.Form("hOndt%-i",ndt);
18311 namebkg.Form("hOffdt%-i",ndt);
18312 varname="dtime";
18313 }
18314 else
18315 {
18316 nametot.Form("hOnZdt%-i",ndt);
18317 namebkg.Form("hOffZdt%-i",ndt);
18318 varname="dtimez";
18319 }
18320 TH1F* hOndt=(TH1F*)fBurstHistos.FindObject(nametot);
18321 TH1F* hOffdt=(TH1F*)fBurstHistos.FindObject(namebkg);
18322
18323 TString title;
18324 Double_t deltatbin=0;
18325 Int_t nOndt=0;
18326 Int_t nOffdt=0;
18327
18328 if (!hOndt)
18329 {
18330 NcSample sOndt=fBurstOnMatch.GetDtSample(varname,ndt);
18331 nOndt=sOndt.GetN();
18332
18333 if (nOndt)
18334 {
18335 hOndt=new TH1F(nametot,"histo",10000,1,0);
18336
18337 hOndt->SetBuffer(nOndt);
18338
18339 for (Int_t i=1; i<=nOndt; i++)
18340 {
18341 hOndt->Fill(sOndt.GetEntry(i,1));
18342 }
18343
18344 hOndt->BufferEmpty(1);
18345
18346 // Create title and labels for this delta t histograms
18347 deltatbin=hOndt->GetXaxis()->GetBinWidth(1);
18348 if (!zcor) title.Form("Time intervals between %-i consecutive events in the on-source time window;dt in %-s;Counts per %-.3g %-s",(ndt+1),tu.Data(),deltatbin,tu.Data());
18349 if (zcor) title.Form("Time intervals between %-i consecutive events in the redshift corrected on-source time window;dt in %-s;Counts per %-.3g %-s",(ndt+1),tu.Data(),deltatbin,tu.Data());
18350 hOndt->SetTitle(title);
18351
18352 fBurstHistos.Add(hOndt);
18353 }
18354 }
18355
18356 if (!hOffdt)
18357 {
18358 NcSample sOffdt=fBurstOffMatch.GetDtSample(varname,ndt);
18359 nOffdt=sOffdt.GetN();
18360
18361 if (nOffdt)
18362 {
18363 hOffdt=new TH1F(namebkg,"histo",10000,1,0);
18364
18365 hOffdt->SetBuffer(nOffdt);
18366
18367 for (Int_t i=1; i<=nOffdt; i++)
18368 {
18369 hOffdt->Fill(sOffdt.GetEntry(i,1));
18370 }
18371
18372 hOffdt->BufferEmpty(1);
18373
18374 // Create title and labels for this delta t histograms
18375 deltatbin=hOffdt->GetXaxis()->GetBinWidth(1);
18376 if (!zcor) title.Form("Time intervals between %-i consecutive events in the off-source time window;dt in %-s;Counts per %-.3g %-s",(ndt+1),tu.Data(),deltatbin,tu.Data());
18377 if (zcor) title.Form("Time intervals between %-i consecutive events in the redshift corrected off-source time window;dt in %-s;Counts per %-.3g %-s",(ndt+1),tu.Data(),deltatbin,tu.Data());
18378 hOffdt->SetTitle(title);
18379
18380 fBurstHistos.Add(hOffdt);
18381 }
18382 }
18383
18384 if (hOndt || hOffdt) cout << " The following arrival time interval (dt) histograms have been generated :" << endl;
18385 if (hOndt) cout << " ... " << hOndt->GetName() << " : " << hOndt->GetTitle() << endl;
18386 if (hOffdt) cout << " ... " << hOffdt->GetName() << " : " << hOffdt->GetTitle() << endl;
18387
18388 if (hOndt) hisdtOn=*hOndt;
18389 if (hOffdt) hisdtOff=*hOffdt;
18390
18391 // Creation of the Poisson based dt PDFs from the observed data for a background only hypothesis
18392
18393 Double_t rateOn=fBurstParameters->GetSignal("rateOn");
18394 Double_t rateOff=fBurstParameters->GetSignal("rateOff");
18395
18396 // Convert the event rates into the correct units
18397 rateOn*=fTfact;
18398 rateOff*=fTfact;
18399
18400 if (zcor) // Redshift corrected arrival times
18401 {
18402 Double_t nevt=fBurstOnMatch.GetN();
18403 Double_t tmin=fBurstOnMatch.GetMinimum(varname);
18404 Double_t tmax=fBurstOnMatch.GetMaximum(varname);
18405 Double_t twin=tmax-tmin;
18406 rateOn=0;
18407 if (twin) rateOn=nevt/twin;
18408 nevt=fBurstOffMatch.GetN();
18409 tmin=fBurstOffMatch.GetMinimum(varname);
18410 tmax=fBurstOffMatch.GetMaximum(varname);
18411 twin=tmax-tmin;
18412 rateOff=0;
18413 if (twin) rateOff=nevt/twin;
18414 }
18415
18416 // Determine the corresponding dt PDFs based on Poisson statistics
18417 // Only the bkg dt PDF is used, since this may be obtained from off-source measurements.
18418 // Using the total dt PDF would artificially lower the sensitivity due to possible signal events.
18419
18420 NcMath math;
18421 pdfdtOn=math.PoissonDtDist(rateOn,ndt); // Poisson dt pdf for the observed on source event rate
18422 pdfdtOff=math.PoissonDtDist(rateOff,ndt); // Poisson dt pdf for the observed off source event rate
18423
18424 if (!zcor)
18425 {
18426 nametot.Form("hpdfOndt%-i",ndt);
18427 namebkg.Form("hpdfOffdt%-i",ndt);
18428 }
18429 else
18430 {
18431 nametot.Form("hpdfOnZdt%-i",ndt);
18432 namebkg.Form("hpdfOffZdt%-i",ndt);
18433 }
18434 TH1* hpdfOndt=(TH1*)fBurstHistos.FindObject(nametot);
18435 TH1* hpdfOffdt=(TH1*)fBurstHistos.FindObject(namebkg);
18436
18437 Double_t xmaxfdt=1;
18438 Double_t deltatmax=0;
18439 if (hOndt)
18440 {
18441 deltatmax=hOndt->GetXaxis()->GetXmax();
18442 xmaxfdt=deltatmax;
18443 }
18444 if (hOffdt)
18445 {
18446 deltatmax=hOffdt->GetXaxis()->GetXmax();
18447 if (deltatmax>xmaxfdt) xmaxfdt=deltatmax;
18448 }
18449 Int_t npx=10000;
18450 pdfdtOn.SetRange(0,xmaxfdt);
18451 pdfdtOn.SetNpx(npx);
18452 pdfdtOff.SetRange(0,xmaxfdt);
18453 pdfdtOff.SetNpx(npx);
18454
18455 // Provide the dt PDFs as histograms in the output file
18456 if (!hpdfOndt && nOndt)
18457 {
18458 hpdfOndt=(TH1*)pdfdtOn.GetHistogram()->Clone();
18459 hpdfOndt->SetName(nametot.Data());
18460 title.Form("dt in %-s",tu.Data());
18461 hpdfOndt->GetXaxis()->SetTitle(title);
18462 fBurstHistos.Add(hpdfOndt);
18463 }
18464
18465 if (!hpdfOffdt && nOffdt)
18466 {
18467 hpdfOffdt=(TH1*)pdfdtOff.GetHistogram()->Clone();
18468 hpdfOffdt->SetName(namebkg.Data());
18469 hpdfOffdt->GetXaxis()->SetTitle(title);
18470 fBurstHistos.Add(hpdfOffdt);
18471 }
18472
18473 if (hpdfOndt || hpdfOffdt) cout << " The following arrival time interval (dt) PDFs have been generated :" << endl;
18474 if (hpdfOndt) cout << " ... " << hpdfOndt->GetName() << " : " << hpdfOndt->GetTitle() << endl;
18475 if (hpdfOffdt) cout << " ... " << hpdfOffdt->GetName() << " : " << hpdfOffdt->GetTitle() << endl;
18476}
18477
18479{
18489
18490 Int_t nh=fBurstHistos.GetEntries();
18491 cout << endl;
18492 cout << " =============== The following " << nh << " histograms have been generated ===============" << endl;
18493 for (Int_t ih=0; ih<nh; ih++)
18494 {
18495 TH1* hx=(TH1*)fBurstHistos.At(ih);
18496 if (!hx) continue;
18497 if (!hx->GetEntries()) continue;
18498 cout << " " << hx->GetName() << " : " << hx->GetTitle() << endl;
18499 }
18500 cout << " ===============================================================================" << endl;
18501}
18502
18504{
18514
18515 // The output file for the produced histograms
18516 TFile fout(filename.Data(),"RECREATE","NcAstrolab analysis results");
18517
18518 // Write all the histos to the output file
18519 Int_t nh=fBurstHistos.GetEntries();
18520 for (Int_t ih=0; ih<nh; ih++)
18521 {
18522 TH1* hx=(TH1*)fBurstHistos.At(ih);
18523 if (!hx) continue;
18524 if (!hx->GetEntries()) continue;
18525 hx->Write();
18526 }
18527
18528 fout.Write();
18529
18530 cout << endl;
18531 cout << " *" << ClassName() << "::WriteBurstHistograms* All generated histograms have been written to file " << filename << endl;
18533}
18534
18536{
18545
18546 if (gROOT->IsBatch())
18547 {
18548 printf("\n *%-s::SkyMapPanel* GUI is not available in batch mode. \n",ClassName());
18549 return;
18550 }
18551
18552 // Select the lab timestamp as default
18553 fMapTS.SetMJD(fMJD,fJsec,fJns,fJps,"A");
18554
18555 // Import current Lab settings
18556 Double_t l=0;
18557 Double_t b=0;
18558 GetLabPosition(l,b,"deg");
18559 fMapLabLocL=l;
18560 fMapLabLocB=b;
18563 // Get the lab timestamp data in the text box
18564 UInt_t year=0;
18565 UInt_t month=0;
18566 UInt_t day=0;
18567 GetDate(kTRUE,0,&year,&month,&day);
18568 GetDayTimeString("UTC",3,0,0,&fMapTime);
18569 fMapDate.Form("%02i-%02i-%-i",day,month,year);
18570 fMapTime.ReplaceAll(" UTC","");
18572 fMapDateTime+="/";
18574
18575 // Re-invokation of the SkyMapPanel
18576 if (fSkyMapPanel)
18577 {
18578 // Import the current lab settings
18579 Int_t idx=1;
18580 TString names[9]={"User","IceCube","RNO-G","ARA","Amanda","WSRT","Astron","Greenwich","ARCA"};
18581 for (Int_t i=1; i<=9; i++)
18582 {
18583 if (names[i-1]==fExperiment) idx=i;
18584 }
18585 fMapLabE->Select(idx,kTRUE);
18586
18587 MapLocEnter();
18588
18589 // The Lab UTC time
18590 fMapTStimetype->Select(1,kTRUE);
18591 MapTimeType(10);
18592
18593 // Map all subwindows of main frame
18594 fSkyMapPanel->MapSubwindows();
18595
18596 // Initialize the layout algorithm
18597 fSkyMapPanel->Resize(fSkyMapPanel->GetDefaultSize());
18598
18599 // Map main frame
18600 fSkyMapPanel->MapWindow();
18601
18602 return;
18603 }
18604
18605 // New initialization of the SkyMapPanel
18606 UInt_t border=5;
18607 fSkyMapPanel=new TGMainFrame(gClient->GetRoot());
18608 fSkyMapPanel->SetWindowName("SkyMapPanel");
18609 fSkyMapPanel->Connect("CloseWindow()","NcAstrolab",this,"MapClose()");
18610
18611 // Define the various sub-frames and fill them with the various panels
18612 TGCompositeFrame* frames[4]={0,0,0,0};
18613 TGLayoutHints* layouts[4]={0,0,0,0};
18614
18615 // The Lab specification and timestamp frame
18616 frames[0]=new TGCompositeFrame(fSkyMapPanel,1,1,kHorizontalFrame|kSunkenFrame);
18617 layouts[0]=new TGLayoutHints(kLHintsExpandX,border,border,0,0);
18618 LabLocationPanel(frames[0]);
18619 TimestampPanel(frames[0]);
18620
18621 // The local reference and info frame
18622 frames[1]=new TGCompositeFrame(fSkyMapPanel,1,1,kHorizontalFrame|kSunkenFrame);
18623 layouts[1]=new TGLayoutHints(kLHintsExpandX,border,border,0,0);
18624 LabLocalFramePanel(frames[1]);
18625 InfoPanel(frames[1]);
18626
18627 // The entries frame
18628 frames[2]=new TGCompositeFrame(fSkyMapPanel,1,1,kHorizontalFrame|kSunkenFrame);
18629 layouts[2]=new TGLayoutHints(kLHintsExpandX,border,border,0,0);
18630 EntriesPanel(frames[2]);
18631
18632 // The drawing/listing options and command buttons frame
18633 frames[3]=new TGCompositeFrame(fSkyMapPanel,1,1,kHorizontalFrame|kSunkenFrame);
18634 layouts[3]=new TGLayoutHints(kLHintsExpandX,border,border,0,0);
18635 MapListOptionsPanel(frames[3]);
18636 CommandPanel(frames[3]);
18637
18638 // Add all subframes to the mainframe
18639 for (Int_t i=0; i<4; i++)
18640 {
18641 if (frames[i]) fSkyMapPanel->AddFrame(frames[i],layouts[i]);
18642 }
18643
18644 // Map all subwindows of main frame
18645 fSkyMapPanel->MapSubwindows();
18646
18647 // Initialize the layout algorithm
18648 fSkyMapPanel->Resize(fSkyMapPanel->GetDefaultSize());
18649
18650 // Map main frame
18651 fSkyMapPanel->MapWindow();
18652}
18653
18654void NcAstrolab::LabLocationPanel(TGCompositeFrame* frame)
18655{
18661
18662 if (!frame) return;
18663
18664 TGGroupFrame* panel=new TGGroupFrame(frame,"Lab longitude, latitude, experiment site and detector ID",kHorizontalFrame);
18665 panel->SetTitlePos(TGGroupFrame::kCenter);
18666 frame->AddFrame(panel);
18667
18668 // The lab longitude entry field
18669 fMapLabLBI[0]=new TGNumberEntryField(panel,-1,fMapLabLocL);
18670 fMapLabLBI[0]->SetToolTipText("Longitude");
18671 fMapLabLBI[0]->Connect("TextChanged(const char*)","NcAstrolab",this,"MapLocl(const char*)");
18672 fMapLabLBI[0]->Resize(65,20);
18673 panel->AddFrame(fMapLabLBI[0]);
18674
18675 // The lab latitude entry field
18676 fMapLabLBI[1]=new TGNumberEntryField(panel,-1,fMapLabLocB);
18677 fMapLabLBI[1]->SetToolTipText("Latitude");
18678 fMapLabLBI[1]->Connect("TextChanged(const char*)","NcAstrolab",this,"MapLocb(const char*)");
18679 fMapLabLBI[1]->Resize(65,20);
18680 panel->AddFrame(fMapLabLBI[1]);
18681
18682 // The lab longitude and latitude type selection box
18683 fMapLabU=new TGComboBox(panel);
18684 fMapLabU->Connect("Selected(Int_t)","NcAstrolab",this,"MapUloc(Int_t)");
18685 fMapLabU->AddEntry("deg",1);
18686 fMapLabU->AddEntry("dms",2);
18687 fMapLabU->AddEntry("hms",3);
18688 fMapLabU->AddEntry("rad",4);
18689 fMapLabU->Resize(50,20);
18690 panel->AddFrame(fMapLabU);
18691 fMapLabU->Select(1,kTRUE);
18692
18693 // The experiment name selection box
18694 fMapLabE=new TGComboBox(panel);
18695 fMapLabE->Connect("Selected(Int_t)","NcAstrolab",this,"MapExperiment(Int_t)");
18696 Int_t idx=1;
18697 TString names[9]={"User","IceCube","RNO-G","ARA","Amanda","WSRT","Astron","Greenwich","ARCA"};
18698 for (Int_t i=1; i<=9; i++)
18699 {
18700 fMapLabE->AddEntry(names[i-1],i);
18701 if (names[i-1]==fExperiment) idx=i;
18702 }
18703 fMapLabE->Resize(90,20);
18704 panel->AddFrame(fMapLabE);
18705 fMapLabE->Select(idx,kTRUE);
18706
18707 // The detector element ID field
18708 fMapLabLBI[2]=new TGNumberEntryField(panel,-1,fLabId,TGNumberFormat::kNESInteger);
18709 fMapLabLBI[2]->SetToolTipText("The (optional) detector element ID (0=global)");
18710 fMapLabLBI[2]->Connect("TextChanged(const char*)","NcAstrolab",this,"MapLocId(const char*)");
18711 fMapLabLBI[2]->Resize(40,20);
18712 panel->AddFrame(fMapLabLBI[2]);
18713
18714 // The button to enter the provided data
18715 TGTextButton* enter=new TGTextButton(panel,"Enter");
18716 enter->SetToolTipText("Enter the provided data");
18717 enter->Connect("Clicked()","NcAstrolab",this,"MapLocEnter()");
18718 TGLayoutHints* Lenter=new TGLayoutHints(kLHintsCenterX,10,0,0,0);
18719 panel->AddFrame(enter,Lenter);
18720
18721 MapLocEnter();
18722}
18723
18724void NcAstrolab::MapLocl(const char* text)
18725{
18731
18732 TString s=text;
18733 fMapLabLocL=s.Atof();
18734}
18735
18736void NcAstrolab::MapLocb(const char* text)
18737{
18743
18744 TString s=text;
18745 fMapLabLocB=s.Atof();
18746}
18747
18749{
18755
18756 TString s[4]={"deg","dms","hms","rad"};
18757 if (i<=4) fMapLabLocU=s[i-1];
18758}
18759
18761{
18767
18768 TString s[9]={"User","IceCube","RNO-G","ARA","Amanda","WSRT","Astron","Greenwich","ARCA"};
18769 if (i<=9) fMapLabExpName=s[i-1];
18770}
18771
18772void NcAstrolab::MapLocId(const char* text)
18773{
18779
18780 TString s=text;
18781 fMapLabId=s.Atoi();
18782}
18783
18785{
18791
18792 fSkyMapPanel->RequestFocus();
18793
18795
18796 if (fMapLabExpName=="User")
18797 {
18798 SetNameTitle("User","Virtual Lab for general use");
18799 MapLocId("0");
18800 printf("\n *** Settings adopted for a virtual lab for general use. *** \n");
18801 }
18802 else
18803 {
18806 // Update the longitude, latitude and detector ID selection boxes
18808 TString s;
18809 s.Form("%-.3f",fMapLabLocL);
18810 fMapLabLBI[0]->SetText(s);
18811 s.Form("%-.3f",fMapLabLocB);
18812 fMapLabLBI[1]->SetText(s);
18813 fMapLabU->Select(1,kTRUE);
18814 MapUloc(1);
18815 s.Form("%-i",fMapLabId);
18816 fMapLabLBI[2]->SetText(s);
18817 printf("\n *** Lab settings adopted for the %-s location. *** \n",fMapLabExpName.Data());
18818 }
18819
18820 // Update the local frame data for the selected lab
18821 TString val;
18822 for (Int_t i=0; i<6; i++)
18823 {
18824 val.Form("%-.2f",fAxes[i]);
18825 if (fMapLabLframe[i]) fMapLabLframe[i]->SetText(val);
18826 }
18827}
18828
18829void NcAstrolab::TimestampPanel(TGCompositeFrame* frame)
18830{
18836
18837 if (!frame) return;
18838
18839 TGGroupFrame* panel=new TGGroupFrame(frame,"Timestamp to be used for Entries, List and Map",kHorizontalFrame);
18840 panel->SetTitlePos(TGGroupFrame::kCenter);
18841 frame->AddFrame(panel);
18842
18843 // The Date/Time textbox
18844 fMapTSdatetime=new TGTextEntry(panel,fMapDateTime.Data());
18845 fMapTSdatetime->SetToolTipText("Date/Time as dd-mm-yyyy/hh:mm:ss.sss or MJD");
18846 fMapTSdatetime->Connect("TextChanged(const char*)","NcAstrolab",this,"MapDateTime(const char*)");
18847 fMapTSdatetime->SetAlignment(kTextRight);
18848 fMapTSdatetime->Resize(170,20);
18849 panel->AddFrame(fMapTSdatetime);
18850
18851 // The Time type selection box
18852 fMapTStimetype=new TGComboBox(panel);
18853 fMapTStimetype->Connect("Selected(Int_t)","NcAstrolab",this,"MapTimeType(Int_t)");
18854 fMapTStimetype->AddEntry("UTC",1);
18855 fMapTStimetype->AddEntry("LMT",2);
18856 fMapTStimetype->AddEntry("UT1",3);
18857 fMapTStimetype->AddEntry("MJD",4);
18858 fMapTStimetype->AddEntry("JD",5);
18859 fMapTStimetype->AddEntry("TJD",6);
18860 fMapTStimetype->AddEntry("Unix",7);
18861 fMapTStimetype->AddEntry("GPS",8);
18862 fMapTStimetype->AddEntry("TAI",9);
18863 fMapTStimetype->AddEntry("TT",10);
18864 fMapTStimetype->AddEntry("SysClock",11);
18865 fMapTStimetype->AddEntry("Lab",12);
18866 fMapTStimetype->AddEntry("EntryName",13);
18867 fMapTStimetype->Resize(100,20);
18868 panel->AddFrame(fMapTStimetype);
18869 fMapTStimetype->Select(1,kTRUE);
18870 MapTimeType(1);
18871
18872 // The Lab TS modification button
18873 TGTextButton* labTS=new TGTextButton(panel,"Store as Lab TS");
18874 labTS->SetToolTipText("Store the current selection as Lab timestamp");
18875 labTS->Connect("Clicked()","NcAstrolab",this,"MapLabTS()");
18876 TGLayoutHints* LlabTS=new TGLayoutHints(kLHintsCenterX,10,0,0,0);
18877 panel->AddFrame(labTS,LlabTS);
18878}
18879
18880void NcAstrolab::MapDateTime(const char* text)
18881{
18887
18888 fMapDateTime=text;
18889}
18890
18892{
18898
18899 TString s[13]={"UTC","LMT","UT1","MJD","JD","TJD","Unix","GPS","TAI","TT","SysClock","Lab","EntryName"};
18900
18901 if (i<=13) fMapTimeType=s[i-1];
18902
18903 if (fMapTimeType=="SysClock" || fMapTimeType=="Lab") SetMapTS();
18904 if (fMapTimeType=="MJD" || fMapTimeType=="JD" || fMapTimeType=="TJD" || fMapTimeType=="Unix" || fMapTimeType.Contains("Name")) fMapTSdatetime->SetText("");
18905}
18906
18908{
18914
18915 SetMapTS();
18916
18917 fSkyMapPanel->RequestFocus();
18918
18919 Int_t mjd,sec,ns;
18920 fMapTS.GetMJD(mjd,sec,ns);
18921 Int_t ps=fMapTS.GetPs();
18922 this->SetMJD(mjd,sec,ns,ps,"U");
18923
18924 printf("\n *** Lab timestamp modified *** \n");
18925}
18926
18927void NcAstrolab::LabLocalFramePanel(TGCompositeFrame* frame)
18928{
18934
18935 if (!frame) return;
18936
18937 TGGroupFrame* panel=new TGGroupFrame(frame,"Local frame axes orientations w.r.t. X0=South, Y0=East, Z0=Zenith)",kHorizontalFrame);
18938 panel->SetTitlePos(TGGroupFrame::kCenter);
18939 frame->AddFrame(panel);
18940
18941 // The local X-axis theta (=zenith) angle w.r.t. the MRF
18942 fMapLabLframe[0]=new TGNumberEntryField(panel,-1,fAxes[0]);
18943 fMapLabLframe[0]->SetToolTipText("Local X-axis zenith angle in deg");
18944 fMapLabLframe[0]->Resize(55,20);
18945 panel->AddFrame(fMapLabLframe[0]);
18946
18947 // The local X-axis phi angle w.r.t. the MRF
18948 fMapLabLframe[1]=new TGNumberEntryField(panel,-1,fAxes[1]);
18949 fMapLabLframe[1]->SetToolTipText("Local X-axis phi angle in deg");
18950 fMapLabLframe[1]->Resize(55,20);
18951 panel->AddFrame(fMapLabLframe[1]);
18952
18953 // The local Y-axis theta (=zenith) angle w.r.t. the MRF
18954 fMapLabLframe[2]=new TGNumberEntryField(panel,-1,fAxes[2]);
18955 fMapLabLframe[2]->SetToolTipText("Local Y-axis zenith angle in deg");
18956 fMapLabLframe[2]->Resize(55,20);
18957 panel->AddFrame(fMapLabLframe[2]);
18958
18959 // The local Y-axis phi angle w.r.t. the MRF
18960 fMapLabLframe[3]=new TGNumberEntryField(panel,-1,fAxes[3]);
18961 fMapLabLframe[3]->SetToolTipText("Local Y-axis phi angle in deg");
18962 fMapLabLframe[3]->Resize(55,20);
18963 panel->AddFrame(fMapLabLframe[3]);
18964
18965 // The local Z-axis theta (=zenith) angle w.r.t. the MRF
18966 fMapLabLframe[4]=new TGNumberEntryField(panel,-1,fAxes[4]);
18967 fMapLabLframe[4]->SetToolTipText("Local Z-axis zenith angle in deg");
18968 fMapLabLframe[4]->Resize(55,20);
18969 panel->AddFrame(fMapLabLframe[4]);
18970
18971 // The local Z-axis phi angle w.r.t. the MRF
18972 fMapLabLframe[5]=new TGNumberEntryField(panel,-1,fAxes[5]);
18973 fMapLabLframe[5]->SetToolTipText("Local Z-axis phi angle in deg");
18974 fMapLabLframe[5]->Resize(55,20);
18975 panel->AddFrame(fMapLabLframe[5]);
18976
18978
18979 // The button to enter the provided data
18980 TGTextButton* enter=new TGTextButton(panel,"Enter");
18981 enter->SetToolTipText("Enter the provided data");
18982 enter->Connect("Clicked()","NcAstrolab",this,"MapLabLframeEnter()");
18983 TGLayoutHints* Lenter=new TGLayoutHints(kLHintsLeft,10,0,0,0);
18984 panel->AddFrame(enter,Lenter);
18985}
18986
18988{
18996
18997 fSkyMapPanel->RequestFocus();
18998
18999 if (fMapLabExpName=="IceCube" || fMapLabExpName=="RNO-G" || fMapLabExpName=="Amanda")
19000 {
19001 printf("\n *** Local frame will NOT be changed for experiment site %-s *** \n",fMapLabExpName.Data());
19002
19003 // Update the local frame data for the selected lab
19004 TString val;
19005 for (Int_t i=0; i<6; i++)
19006 {
19007 val.Form("%-.2f",fAxes[i]);
19008 if (fMapLabLframe[i]) fMapLabLframe[i]->SetText(val);
19009 }
19010 return;
19011 }
19012
19013 for (Int_t i=0; i<6; i++)
19014 {
19015 fAxes[i]=fMapLabLframe[i]->GetNumber();
19016 }
19017
19018 SetLocalFrame(fAxes[0],fAxes[1],fAxes[2],fAxes[3],fAxes[4],fAxes[5]);
19019}
19020
19021void NcAstrolab::InfoPanel(TGCompositeFrame* frame)
19022{
19028
19029 if (!frame) return;
19030
19031 TGGroupFrame* panel=new TGGroupFrame(frame,"Informative output",kHorizontalFrame);
19032 panel->SetTitlePos(TGGroupFrame::kCenter);
19033 frame->AddFrame(panel);
19034
19035 // The info category selection box
19036 TGComboBox* cinfo=new TGComboBox(panel);
19037 cinfo->Connect("Selected(Int_t)","NcAstrolab",this,"MapCinfo(Int_t)");
19038 cinfo->AddEntry("Lab",1);
19039 cinfo->AddEntry("TSbox",2);
19040 cinfo->AddEntry("Entry",3);
19041 cinfo->AddEntry("Nstore",4);
19042 cinfo->Resize(60,20);
19043 panel->AddFrame(cinfo);
19044 cinfo->Select(1,kTRUE);
19045 MapCinfo(1);
19046
19047 // The lab info time type selection box
19048 TGComboBox* tinfo=new TGComboBox(panel);
19049 tinfo->Connect("Selected(Int_t)","NcAstrolab",this,"MapTinfo(Int_t)");
19050 tinfo->AddEntry("LAT/LAST",1);
19051 tinfo->AddEntry("LMT/LMST",2);
19052 tinfo->AddEntry("Julian",3);
19053 tinfo->AddEntry("UT1",4);
19054 tinfo->AddEntry("UTC",5);
19055 tinfo->AddEntry("TAI",6);
19056 tinfo->AddEntry("GPS",7);
19057 tinfo->AddEntry("TT",8);
19058 tinfo->AddEntry("Unix",9);
19059 tinfo->Resize(85,20);
19060 panel->AddFrame(tinfo);
19061 tinfo->Select(1,kTRUE);
19062 MapTinfo(1);
19063
19064 // The lab info longitude and latitude type selection box
19065 TGComboBox* uinfo=new TGComboBox(panel);
19066 uinfo->Connect("Selected(Int_t)","NcAstrolab",this,"MapUinfo(Int_t)");
19067 uinfo->AddEntry("deg",1);
19068 uinfo->AddEntry("dms",2);
19069 uinfo->AddEntry("hms",3);
19070 uinfo->AddEntry("rad",4);
19071 uinfo->Resize(50,20);
19072 panel->AddFrame(uinfo);
19073 uinfo->Select(1,kTRUE);
19074 MapUinfo(1);
19075
19076 // The entry name textbox
19077 TGTextEntry* mapiname=new TGTextEntry(panel,"");
19078 mapiname->SetToolTipText("Stored entry name for info");
19079 mapiname->Connect("TextChanged(const char*)","NcAstrolab",this,"MapIname(const char*)");
19080 mapiname->SetAlignment(kTextRight);
19081 mapiname->Resize(100,20);
19082 panel->AddFrame(mapiname);
19083
19084 // The info button
19085 TGTextButton* info=new TGTextButton(panel,"Info");
19086 info->Connect("Clicked()","NcAstrolab",this,"MapInfo()");
19087 info->SetToolTipText("Provide info on the specified item");
19088 TGLayoutHints* Linfo=new TGLayoutHints(kLHintsLeft,10,0,0,0);
19089 panel->AddFrame(info,Linfo);
19090}
19091
19093{
19099
19100 TString s[4]={"Lab","TS box","EntryName","Nstore"};
19101 if (i<=4) fMapCinfo=s[i-1];
19102}
19103
19105{
19111
19112 if (i==1)
19113 {
19114 fMapTinfo=-1;
19115 }
19116 else
19117 {
19118 fMapTinfo=i-1;
19119 }
19120}
19121
19123{
19129
19130 TString s[4]={"deg","dms","hms","rad"};
19131 if (i<=4) fMapUinfo=s[i-1];
19132}
19133
19134void NcAstrolab::MapIname(const char* text)
19135{
19141
19142 fMapIname=text;
19143}
19144
19146{
19152
19153 SetMapTS();
19154
19155 TString modes[9]={"LAT/LAST","LMT/LMST","Julian","UT1","UTC","TAI","GPS","TT","Unix"};
19156 TString datetime;
19157
19158 if (fMapCinfo=="Nstore")
19159 {
19160 Int_t nref=GetNsignals(0);
19161 Int_t nmeas=GetNsignals(1);
19162 Int_t ntot=nref+nmeas;
19163 printf("\n *** Info about the stored entries *** \n");
19164 printf(" Ntotal=%-i Nrefs=%-i Nmeas=%-i \n",ntot,nref,nmeas);
19165 }
19166 else if (fMapCinfo=="Lab")
19167 {
19168 if (fMapTinfo<3)
19169 {
19170 printf("\n *** Info about the current Lab settings *** \n");
19172 }
19173 else
19174 {
19175 printf("\n *** Info for the Lab timestamp *** \n");
19176 if (fMapTinfo==8)
19177 {
19178 printf(" Unix time : %-.12f \n",GetUnixTime());
19179 }
19180 else
19181 {
19182 datetime=GetDayTimeString(modes[fMapTinfo],12);
19183 printf(" %-s \n",datetime.Data());
19184 }
19185 }
19186 }
19187 else if (fMapCinfo.Contains("TS"))
19188 {
19189 printf("\n *** Info for the timestamp in the user selection box *** \n");
19190 if (fMapTinfo<3)
19191 {
19192 printf(" Lab time offset w.r.t. UT : "); PrintTime(fToffset,12); printf("\n");
19194 fMapTS.Date(4);
19195 }
19196 else
19197 {
19198 if (fMapTinfo==8)
19199 {
19200 printf(" Unix time : %-.12f \n",fMapTS.GetUnixTime());
19201 }
19202 else
19203 {
19204 datetime=fMapTS.GetDayTimeString(modes[fMapTinfo],12);
19205 printf(" %-s \n",datetime.Data());
19206 }
19207 }
19208 }
19209 else // Information of the specified entry name
19210 {
19211 NcSignal* sx=0;
19212 NcTimestamp* tx=0;
19213 sx=GetSignal(fMapIname,0);
19214 if(!sx) sx=GetSignal(fMapIname,1);
19215 if (sx)
19216 {
19217 printf("\n *** Info for entry : %-s *** \n",fMapIname.Data());
19218 sx->Data("sph",fMapUinfo);
19219 tx=sx->GetTimestamp();
19220 if (tx)
19221 {
19222 NcTimestamp tx2(*tx);
19224 if (fMapTinfo<3)
19225 {
19226 printf(" Lab time offset w.r.t. UT : "); PrintTime(fToffset,12); printf("\n");
19227 tx2.Date(fMapTinfo,fToffset);
19228 tx2.Date(4);
19229 }
19230 else
19231 {
19232 if (fMapTinfo==8)
19233 {
19234 printf(" Unix time : %-.12f \n",tx2.GetUnixTime());
19235 }
19236 else
19237 {
19238 datetime=tx2.GetDayTimeString(modes[fMapTinfo],12);
19239 printf(" %-s \n",datetime.Data());
19240 }
19241 }
19242 }
19243 }
19244 else
19245 {
19246 printf("\n *** No entry found with name : %-s *** \n",fMapIname.Data());
19247 }
19248 }
19249}
19250
19251void NcAstrolab::EntriesPanel(TGCompositeFrame* frame)
19252{
19258
19259 if (!frame) return;
19260
19261 TGGroupFrame* panel=new TGGroupFrame(frame,"Entries in (a,b) coordinates",kHorizontalFrame);
19262 panel->SetTitlePos(TGGroupFrame::kCenter);
19263 frame->AddFrame(panel);
19264
19265 // The a coordinate entry field
19266 TGNumberEntryField* ea=new TGNumberEntryField(panel,-1,0);
19267 ea->SetToolTipText("Angle a");
19268 ea->Connect("TextChanged(const char*)","NcAstrolab",this,"MapEa(const char*)");
19269 ea->Resize(100,20);
19270 panel->AddFrame(ea);
19271 MapEa("0");
19272
19273 // The a coordinate type selection box
19274 TGComboBox* ua=new TGComboBox(panel);
19275 ua->Connect("Selected(Int_t)","NcAstrolab",this,"MapUa(Int_t)");
19276 ua->AddEntry("deg",1);
19277 ua->AddEntry("dms",2);
19278 ua->AddEntry("hms",3);
19279 ua->AddEntry("rad",4);
19280 ua->AddEntry("hrs",5);
19281 ua->Resize(50,20);
19282 panel->AddFrame(ua);
19283 ua->Select(1,kTRUE);
19284 MapUa(1);
19285
19286 // The b coordinate entry field
19287 TGNumberEntryField* eb=new TGNumberEntryField(panel,-1,0);
19288 eb->SetToolTipText("Angle b");
19289 eb->Connect("TextChanged(const char*)","NcAstrolab",this,"MapEb(const char*)");
19290 eb->Resize(100,20);
19291 panel->AddFrame(eb);
19292 MapEb("0");
19293
19294 // The b coordinate type selection box
19295 TGComboBox* ub=new TGComboBox(panel);
19296 ub->Connect("Selected(Int_t)","NcAstrolab",this,"MapUb(Int_t)");
19297 ub->AddEntry("deg",1);
19298 ub->AddEntry("dms",2);
19299 ub->AddEntry("hms",3);
19300 ub->AddEntry("rad",4);
19301 ub->AddEntry("hrs",5);
19302 ub->Resize(50,20);
19303 panel->AddFrame(ub);
19304 ub->Select(1,kTRUE);
19305 MapUb(1);
19306
19307 TGComboBox* ecoords=new TGComboBox(panel);
19308 ecoords->Connect("Selected(Int_t)","NcAstrolab",this,"MapEcoord(Int_t)");
19309 ecoords->AddEntry("(ra,dec) (J2000)",1);
19310 ecoords->AddEntry("(ra,dec) (Mean)",2);
19311 ecoords->AddEntry("(ra,dec) (True)",3);
19312 ecoords->AddEntry("(ra,dec) (B1950)",4);
19313 ecoords->AddEntry("Galactic (l,b)",5);
19314 ecoords->AddEntry("Ecliptic (l,b)",6);
19315 ecoords->AddEntry("Horizon (azi,zen)",7);
19316 ecoords->AddEntry("ICR (l,b)",8);
19317 ecoords->AddEntry("Local (theta,phi)",9);
19318 ecoords->AddEntry("pdir (theta,phi)",10);
19319 ecoords->Resize(125,20);
19320 panel->AddFrame(ecoords);
19321 ecoords->Select(1,kTRUE);
19322 MapEcoord(1);
19323
19324 // The signal type
19325 TGComboBox* etypes=new TGComboBox(panel);
19326 etypes->Connect("Selected(Int_t)","NcAstrolab",this,"MapEtype(Int_t)");
19327 etypes->AddEntry("Meas",1);
19328 etypes->AddEntry("Ref",2);
19329 etypes->Resize(55,20);
19330 panel->AddFrame(etypes);
19331 etypes->Select(1,kTRUE);
19332 MapEtype(1);
19333
19334 // The (optional) signal name
19335 TGTextEntry* ename=new TGTextEntry(panel,"");
19336 ename->SetToolTipText("The (optional) entry name");
19337 ename->Connect("TextChanged(const char*)","NcAstrolab",this,"MapEname(const char*)");
19338 ename->SetAlignment(kTextRight);
19339 ename->Resize(100,20);
19340 panel->AddFrame(ename);
19341
19342 // The button to Enter the entry
19343 TGTextButton* enter=new TGTextButton(panel,"Enter");
19344 enter->SetToolTipText("Enter the provided entry");
19345 enter->Connect("Clicked()","NcAstrolab",this,"MapEnter()");
19346 TGLayoutHints* Lenter=new TGLayoutHints(kLHintsCenterX,10,0,0,0);
19347 panel->AddFrame(enter,Lenter);
19348
19349 // The button to Remove the entry
19350 TGTextButton* remove=new TGTextButton(panel,"Remove");
19351 remove->SetToolTipText("Remove the entry specified by type and name pattern (name=* means all)");
19352 remove->Connect("Clicked()","NcAstrolab",this,"MapRemove()");
19353 TGLayoutHints* Lremove=new TGLayoutHints(kLHintsCenterX,10,0,0,0);
19354 panel->AddFrame(remove,Lremove);
19355}
19356
19357void NcAstrolab::MapEa(const char* text)
19358{
19364
19365 TString s=text;
19366 fMapEa=s.Atof();
19367}
19368
19370{
19376
19377 TString s[5]={"deg","dms","hms","rad","hrs"};
19378 if (i<=5) fMapEua=s[i-1];
19379}
19380
19381void NcAstrolab::MapEb(const char* text)
19382{
19388
19389 TString s=text;
19390 fMapEb=s.Atof();
19391}
19392
19394{
19400
19401 TString s[5]={"deg","dms","hms","rad","hrs"};
19402 if (i<=5) fMapEub=s[i-1];
19403}
19404
19406{
19412
19413 TString system[10]={"equ","equ","equ","equ","gal","ecl","hor","icr","loc","pdir"};
19414 TString mode[4]={"J","M","T","B"};
19415
19416 if (i<=10) fMapEcoord=system[i-1];
19417
19418 if (i<=4) fMapEmode=mode[i-1];
19419}
19420
19422{
19428
19429 fMapEtype=1;
19430 if (i==2) fMapEtype=0;
19431}
19432
19433void NcAstrolab::MapEname(const char* text)
19434{
19440
19441 fMapEname=text;
19442}
19443
19445{
19451
19452 SetMapTS(); // Set the selected timestamp
19453
19454 fSkyMapPanel->RequestFocus();
19455
19457
19458 printf("\n *** Specified entry stored *** \n");
19459}
19460
19462{
19468
19469 SetMapTS(); // Set the selected timestamp
19470
19471 fSkyMapPanel->RequestFocus();
19472
19473 Int_t nrem=0;
19475
19476 printf("\n *** Number of specified entries have been removed : %-i *** \n",nrem);
19477}
19478
19479void NcAstrolab::MapListOptionsPanel(TGCompositeFrame* frame)
19480{
19486
19487 if (!frame) return;
19488
19489 TGGroupFrame* panel=new TGGroupFrame(frame,"Map/List options for the (a,b) coordinates",kHorizontalFrame);
19490 panel->SetTitlePos(TGGroupFrame::kCenter);
19491 frame->AddFrame(panel);
19492
19493 // A frame with various additional settings
19494 TGVerticalFrame* render=new TGVerticalFrame(panel,1,1);
19495 panel->AddFrame(render);
19496
19497 // The coordinate system selection box
19498 TGGroupFrame* coordsys=new TGGroupFrame(render,"Coordinate system",kHorizontalFrame);
19499 coordsys->SetTitlePos(TGGroupFrame::kCenter);
19500 render->AddFrame(coordsys);
19501 TGComboBox* dcoords=new TGComboBox(coordsys);
19502 dcoords->Connect("Selected(Int_t)","NcAstrolab",this,"MapDcoord(Int_t)");
19503 dcoords->AddEntry("Equatorial (J2000)",1);
19504 dcoords->AddEntry("Equatorial (Mean)",2);
19505 dcoords->AddEntry("Equatorial (True)",3);
19506 dcoords->AddEntry("Equatorial (B1950)",4);
19507 dcoords->AddEntry("Galactic",5);
19508 dcoords->AddEntry("Ecliptic",6);
19509 dcoords->AddEntry("Horizon",7);
19510 dcoords->AddEntry("ICR",8);
19511 dcoords->AddEntry("Local",9);
19512 dcoords->Resize(140,20);
19513 coordsys->AddFrame(dcoords);
19514 dcoords->Select(1,kTRUE);
19515 MapDcoord(1);
19516
19517 // The Map representation selection box
19518 TGGroupFrame* mapview=new TGGroupFrame(render,"Map representation",kHorizontalFrame);
19519 mapview->SetTitlePos(TGGroupFrame::kCenter);
19520 render->AddFrame(mapview);
19521 TGComboBox* projs=new TGComboBox(mapview);
19522 projs->Connect("Selected(Int_t)","NcAstrolab",this,"MapProj(Int_t)");
19523 projs->AddEntry("Hammer projection",1);
19524 projs->AddEntry("Aitoff projection",2);
19525 projs->AddEntry("Mercator projection",3);
19526 projs->AddEntry("sin(b) vs. a",4);
19527 projs->AddEntry("b vs. a",5);
19528 projs->AddEntry("b vs. UT (0-24 hrs)",6);
19529 projs->AddEntry("b vs. LT (0-24 hrs)",7);
19530 projs->AddEntry("b vs. GST (0-24 hrs)",8);
19531 projs->AddEntry("b vs. LST (0-24 hrs)",9);
19532 projs->AddEntry("b vs. Day at UT",10);
19533 projs->AddEntry("b vs. Day at LT",11);
19534 projs->AddEntry("b vs. Day at GST",12);
19535 projs->AddEntry("b vs. Day at LST",13);
19536 projs->Resize(150,20);
19537 mapview->AddFrame(projs);
19538 projs->Select(1,kTRUE);
19539 MapProj(1);
19540
19541 // The meridian representation options
19542 TGGroupFrame* meridian=new TGGroupFrame(render,"Meridian ordering",kHorizontalFrame);
19543 meridian->SetTitlePos(TGGroupFrame::kCenter);
19544 render->AddFrame(meridian);
19545
19546 // The meridian mode selection box
19547 TGComboBox* mermode=new TGComboBox(meridian);
19548 mermode->Connect("Selected(Int_t)","NcAstrolab",this,"MapMerMode(Int_t)");
19549 mermode->AddEntry("Auto",1);
19550 mermode->AddEntry("---->",2);
19551 mermode->AddEntry("<----",3);
19552 mermode->Resize(55,20);
19553 meridian->AddFrame(mermode);
19554 mermode->Select(1,kTRUE);
19555 MapMerMode(1);
19556
19557 // The meridian central value
19558 TGNumberEntryField* merc=new TGNumberEntryField(meridian,-1,0);
19559 merc->SetToolTipText("Central meridian position");
19560 merc->Connect("TextChanged(const char*)","NcAstrolab",this,"MapMerC(const char*)");
19561 merc->Resize(65,20);
19562 meridian->AddFrame(merc);
19563 MapMerC("0");
19564
19565 // The meridian central value type selection box
19566 TGComboBox* meruc=new TGComboBox(meridian);
19567 meruc->Connect("Selected(Int_t)","NcAstrolab",this,"MapMerUc(Int_t)");
19568 meruc->AddEntry("deg",1);
19569 meruc->AddEntry("dms",2);
19570 meruc->AddEntry("hms",3);
19571 meruc->AddEntry("rad",4);
19572 meruc->Resize(50,20);
19573 meridian->AddFrame(meruc);
19574 meruc->Select(1,kTRUE);
19575 MapMerUc(1);
19576
19577 // The options group
19578 TGVButtonGroup* options=new TGVButtonGroup(panel,"Options");
19579 options->SetTitlePos(TGGroupFrame::kCenter);
19580 options->Connect("Clicked(Int_t)","NcAstrolab",this,"MapDoptions(Int_t)");
19581 TGCheckButton* bhist=new TGCheckButton(options,"Hist");
19582 bhist->SetToolTipText("Project data in a histogram");
19583 TGCheckButton* bclr=new TGCheckButton(options,"Clr");
19584 bclr->SetToolTipText("Clear display before drawing");
19585 TGCheckButton* bref=new TGCheckButton(options,"Ref");
19586 bref->SetToolTipText("Display reference signals");
19587 TGCheckButton* bmeas=new TGCheckButton(options,"Meas");
19588 bmeas->SetToolTipText("Display measured signals");
19589 TGCheckButton* brefts=new TGCheckButton(options,"RefTS");
19590 brefts->SetToolTipText("Display/list each reference signal using its actual recorded timestamp");
19591 panel->AddFrame(options);
19592 options->Show();
19593 options->SetButton(1,kFALSE);
19594 options->SetButton(2,kTRUE);
19595 options->SetButton(3,kTRUE);
19596 options->SetButton(4,kTRUE);
19597 options->SetButton(5,kFALSE);
19598 fMapDoptions[0]=kFALSE;
19599 fMapDoptions[1]=kTRUE;
19600 fMapDoptions[2]=kTRUE;
19601 fMapDoptions[3]=kTRUE;
19602 fMapDoptions[4]=kFALSE;
19603
19604 // The Nmax entry field
19605 TGNumberEntryField* nmax=new TGNumberEntryField(options,-1,-1,TGNumberFormat::kNESInteger);
19606 nmax->SetToolTipText("Max. number of Drawn/Listed entries per type (-1=all)");
19607 nmax->Connect("TextChanged(const char*)","NcAstrolab",this,"MapNmax(const char*)");
19608 nmax->Resize(40,20);
19609 options->AddFrame(nmax);
19610 MapNmax("-1");
19611
19612 // The signal name pattern for matching
19613 TGTextEntry* sname=new TGTextEntry(options,"*");
19614 sname->SetToolTipText("The requested entry name pattern (*=all)");
19615 sname->Connect("TextChanged(const char*)","NcAstrolab",this,"MapDname(const char*)");
19616 sname->SetAlignment(kTextRight);
19617 sname->Resize(100,20);
19618 TGLayoutHints* Lsname=new TGLayoutHints(kLHintsLeft,0,0,5,0);
19619 options->AddFrame(sname,Lsname);
19620 MapDname("*");
19621
19622 // The Ndigs entry field
19623 TGNumberEntryField* ndigs=new TGNumberEntryField(options,-1,1,TGNumberFormat::kNESInteger);
19624 ndigs->SetToolTipText("Number of digits for the listed entries");
19625 ndigs->Connect("TextChanged(const char*)","NcAstrolab",this,"MapNdigs(const char*)");
19626 ndigs->Resize(40,20);
19627 options->AddFrame(ndigs);
19628 MapNdigs("1");
19629
19630 // A frame with various additional settings
19631 TGVerticalFrame* others=new TGVerticalFrame(panel,1,1);
19632 panel->AddFrame(others);
19633
19634 // The Marker size frame
19635 TGGroupFrame* markers=new TGGroupFrame(others,"Marker settings",kHorizontalFrame);
19636 markers->SetTitlePos(TGGroupFrame::kCenter);
19637 others->AddFrame(markers);
19638
19639 // The marker size
19640 TGNumberEntryField* marksize=new TGNumberEntryField(markers,-1,1);
19641 marksize->SetToolTipText("Marker size");
19642 marksize->Connect("TextChanged(const char*)","NcAstrolab",this,"MapMarkSize(const char*)");
19643 marksize->Resize(40,20);
19644 markers->AddFrame(marksize);
19645 MapMarkSize("1");
19646
19647 // The marker style
19648 TGComboBox* markstyle=new TGComboBox(markers);
19649 markstyle->Connect("Selected(Int_t)","NcAstrolab",this,"MapMarkStyle(Int_t)");
19650 markstyle->AddEntry("Dot",1);
19651 markstyle->AddEntry("Star",2);
19652 markstyle->AddEntry("Square",3);
19653 markstyle->AddEntry("Utriangle",4);
19654 markstyle->AddEntry("Dtriangle",5);
19655 markstyle->AddEntry("Diamond",6);
19656 markstyle->AddEntry("Cross",7);
19657 markstyle->AddEntry("Ast",8);
19658 markstyle->AddEntry("Plus",9);
19659 markstyle->AddEntry("Times",10);
19660 markstyle->AddEntry("Circle",11);
19661 markstyle->AddEntry("oStar",12);
19662 markstyle->AddEntry("oSquare",13);
19663 markstyle->AddEntry("oUtriangle",14);
19664 markstyle->AddEntry("oDtriangle",15);
19665 markstyle->AddEntry("oDiamond",16);
19666 markstyle->AddEntry("oCross",17);
19667 markstyle->Resize(90,20);
19668 markers->AddFrame(markstyle);
19669 markstyle->Select(1,kTRUE);
19670 MapMarkStyle(1);
19671
19672 // The marker color selection box
19673 TGComboBox* markcolor=new TGComboBox(markers);
19674 markcolor->Connect("Selected(Int_t)","NcAstrolab",this,"MapMarkColor(Int_t)");
19675 markcolor->AddEntry("Black",1);
19676 markcolor->AddEntry("Red",2);
19677 markcolor->AddEntry("Blue",3);
19678 markcolor->AddEntry("Green",4);
19679 markcolor->AddEntry("Yellow",5);
19680 markcolor->AddEntry("Magenta",6);
19681 markcolor->AddEntry("Cyan",7);
19682 markcolor->AddEntry("Orange",8);
19683 markcolor->AddEntry("Violet",9);
19684 markcolor->AddEntry("Pink",10);
19685 markcolor->AddEntry("Azure",11);
19686 markcolor->AddEntry("Spring",12);
19687 markcolor->AddEntry("Teal",13);
19688 markcolor->AddEntry("Gray",14);
19689 markcolor->AddEntry("White",15);
19690 markcolor->Resize(80,20);
19691 markers->AddFrame(markcolor);
19692 markcolor->Select(3,kTRUE);
19693 MapMarkColor(3);
19694
19695 // The marker type selection box
19696 TGComboBox* marktype=new TGComboBox(markers);
19697 marktype->Connect("Selected(Int_t)","NcAstrolab",this,"MapMarkType(Int_t)");
19698 marktype->AddEntry("Ref",1);
19699 marktype->AddEntry("Meas",2);
19700 marktype->AddEntry("GC",3);
19701 marktype->AddEntry("Grid",4);
19702 marktype->Resize(55,20);
19703 markers->AddFrame(marktype);
19704 marktype->Select(2,kTRUE);
19705 MapMarkType(2);
19706
19707 // The Solar system group
19708 TGGroupFrame* solar=new TGGroupFrame(others,"Selection of Solar system reference objects",kHorizontalFrame);
19709 solar->SetTitlePos(TGGroupFrame::kCenter);
19710 others->AddFrame(solar);
19711
19712 TGButtonGroup* Ssolar=new TGButtonGroup(solar,0,3,5);
19713 Ssolar->SetTitlePos(TGGroupFrame::kCenter);
19714 Ssolar->Connect("Clicked(Int_t)","NcAstrolab",this,"MapSolar(Int_t)");
19715 TGCheckButton* bsun=new TGCheckButton(Ssolar,"Sun");
19716 bsun->SetToolTipText("Enter/Remove the Sun as a reference entry");
19717 TGCheckButton* bmoon=new TGCheckButton(Ssolar,"Moon");
19718 bmoon->SetToolTipText("Enter/Remove the Moon as a reference entry");
19719 TGCheckButton* bmercury=new TGCheckButton(Ssolar,"Mercury");
19720 bmercury->SetToolTipText("Enter/Remove Mercury as a reference entry");
19721 TGCheckButton* bvenus=new TGCheckButton(Ssolar,"Venus");
19722 bvenus->SetToolTipText("Enter/Remove Venus as a reference entry");
19723 TGCheckButton* bearth=new TGCheckButton(Ssolar,"Earth");
19724 bearth->SetToolTipText("Enter/Remove the Earth as a reference entry");
19725 TGCheckButton* bmars=new TGCheckButton(Ssolar,"Mars");
19726 bmars->SetToolTipText("Enter/Remove Mars as a reference entry");
19727 TGCheckButton* bjupiter=new TGCheckButton(Ssolar,"Jupiter");
19728 bjupiter->SetToolTipText("Enter/Remove Jupiter as a reference entry");
19729 TGCheckButton* bsaturn=new TGCheckButton(Ssolar,"Saturn");
19730 bsaturn->SetToolTipText("Enter/Remove Saturn as a reference entry");
19731 TGCheckButton* buranus=new TGCheckButton(Ssolar,"Uranus");
19732 buranus->SetToolTipText("Enter/Remove Uranus as a reference entry");
19733 TGCheckButton* bneptune=new TGCheckButton(Ssolar,"Neptune");
19734 bneptune->SetToolTipText("Enter/Remove Neptune as a reference entry");
19735 solar->AddFrame(Ssolar);
19736 Ssolar->Show();
19737 Ssolar->SetButton(1,kFALSE);
19738 Ssolar->SetButton(2,kFALSE);
19739 Ssolar->SetButton(3,kFALSE);
19740 Ssolar->SetButton(4,kFALSE);
19741 Ssolar->SetButton(5,kFALSE);
19742 Ssolar->SetButton(6,kFALSE);
19743 Ssolar->SetButton(7,kFALSE);
19744 Ssolar->SetButton(8,kFALSE);
19745 Ssolar->SetButton(9,kFALSE);
19746 Ssolar->SetButton(10,kFALSE);
19747 for (Int_t i=0; i<10; i++)
19748 {
19749 fMapSolar[i]=kFALSE;
19750 }
19751
19752 // The Solar system Enter and Remove command buttons
19753 TGVerticalFrame* comms=new TGVerticalFrame(solar,1,1);
19754 TGLayoutHints* Lcomms=new TGLayoutHints(kLHintsLeft,10,0,15,0);
19755 solar->AddFrame(comms,Lcomms); // Command buttons
19756
19757 // The button to Enter the solar system entries
19758 TGTextButton* enter=new TGTextButton(comms,"Enter");
19759 enter->SetToolTipText("Enter the selected Solar system objects as reference signals");
19760 enter->Connect("Clicked()","NcAstrolab",this,"MapEnterSolar()");
19761 TGLayoutHints* Lenter=new TGLayoutHints(kLHintsCenterX,0,0,10,15);
19762 comms->AddFrame(enter,Lenter);
19763
19764 // The button to Remove the solar system entries
19765 TGTextButton* remove=new TGTextButton(comms,"Remove");
19766 remove->SetToolTipText("Remove the selected Solar system objects from the reference signals");
19767 remove->Connect("Clicked()","NcAstrolab",this,"MapRemoveSolar()");
19768 TGLayoutHints* Lremove=new TGLayoutHints(kLHintsCenterX,0,0,0,0);
19769 comms->AddFrame(remove,Lremove);
19770}
19771
19773{
19779
19780 TString system[9]={"equ","equ","equ","equ","gal","ecl","hor","icr","loc"};
19781 TString mode[4]={"J","M","T","B"};
19782
19783 if (i<=9) fMapDcoord=system[i-1];
19784
19785 if (i<=4) fMapDmode=mode[i-1];
19786}
19787
19789{
19795
19796 TString s[13]={"ham","ait","mer","ang","cyl","UTh","LTh","GSTh","LSTh","UYh","LYh","GSYh","LSYh"};
19797 TString sh[13]={"hamh","aith","merh","angh","cylh","UTh","LTh","GSTh","LSTh","UYh","LYh","GSYh","LSYh"};
19798 if (!fMapDoptions[0] && i<13) fMapProj=s[i-1];
19799 if (fMapDoptions[0] && i<13) fMapProj=sh[i-1];
19800 for (Int_t k=0; k<13; k++)
19801 {
19802 if (fMapDoptions[0] && fMapProj==s[k]) fMapProj=sh[k];
19803 if (!fMapDoptions[0] && fMapProj==sh[k]) fMapProj=s[k];
19804 }
19805}
19806
19808{
19814
19815 Int_t modes[3]={0,1,-1};
19816 if (i<=3) fMapMerMode=modes[i-1];
19817}
19818
19819void NcAstrolab::MapMerC(const char* text)
19820{
19826
19827 TString s=text;
19828 fMapMerC=s.Atof();
19829}
19830
19832{
19838
19839 TString s[4]={"deg","dms","hms","rad"};
19840 if (i<=4) fMapMerUc=s[i-1];
19841}
19842
19844{
19850
19851 if (i>5) return;
19852
19853 if (!fMapDoptions[i-1])
19854 {
19855 fMapDoptions[i-1]=1;
19856 }
19857 else
19858 {
19859 fMapDoptions[i-1]=0;
19860 }
19861 if (i==1) MapProj(14); // Set histogram selection
19862}
19863
19864void NcAstrolab::MapNmax(const char* text)
19865{
19871
19872 TString s=text;
19873 fMapNmax=s.Atoi();
19874}
19875
19876void NcAstrolab::MapNdigs(const char* text)
19877{
19883
19884 TString s=text;
19885 fMapNdigs=s.Atoi();
19886}
19887
19888void NcAstrolab::MapDname(const char* text)
19889{
19895
19896 fMapDname=text;
19897}
19898
19899void NcAstrolab::MapMarkSize(const char* text)
19900{
19906
19907 TString s=text;
19908 fMapMarkSize=s.Atof();
19909}
19910
19912{
19918
19919 Int_t styles[17]={8,29,21,22,23,33,34,31,2,5,24,30,25,26,32,27,28};
19920
19921 if (i>17) return;
19922
19923 fMapMarkStyle=styles[i-1];
19924}
19925
19927{
19933
19934 Int_t colors[15]={kBlack,kRed,kBlue,kGreen,kYellow,kMagenta,kCyan,kOrange,kViolet,kPink,kAzure,kSpring,kTeal,kGray,kWhite};
19935
19936 if (i>15) return;
19937
19938 fMapMarkColor=colors[i-1];
19939}
19940
19942{
19948
19949 if (i<=4) fMapMarkType=i-1;
19950}
19951
19953{
19959
19960 if (i>10) return;
19961
19962 if (!fMapSolar[i-1])
19963 {
19964 fMapSolar[i-1]=1;
19965 }
19966 else
19967 {
19968 fMapSolar[i-1]=0;
19969 }
19970}
19971
19973{
19979
19980 TString names[10]={"Sun","Moon","Mercury","Venus","Earth","Mars","Jupiter","Saturn","Uranus","Neptune"};
19981
19982 SetMapTS(); // Get the selected timestamp
19983
19984 fSkyMapPanel->RequestFocus();
19985
19986 for (Int_t i=0; i<10; i++)
19987 {
19988 if (fMapSolar[i]) GetSignal(names[i],0,&fMapTS);
19989 }
19990 printf("\n *** Selected Solar system object(s) entered *** \n");
19991}
19992
19994{
20000
20001 TString names[10]={"Sun","Moon","Mercury","Venus","Earth","Mars","Jupiter","Saturn","Uranus","Neptune"};
20002
20003 SetMapTS(); // Get the selected timestamp
20004
20005 fSkyMapPanel->RequestFocus();
20006
20007 Int_t nrem=0;
20008 Int_t nremx=0;
20009 for (Int_t i=0; i<10; i++)
20010 {
20011 if (fMapSolar[i])
20012 {
20013 nremx=RemoveSignal(names[i],0,1);
20014 if (nremx) nrem++;
20015 }
20016 }
20017
20018 printf("\n *** Number of Solar system object that have been removed : %-i *** \n",nrem);
20019}
20020
20021void NcAstrolab::CommandPanel(TGCompositeFrame* frame)
20022{
20028
20029 if (!frame) return;
20030
20031 TGGroupFrame* panel=new TGGroupFrame(frame,"Commands",kVerticalFrame);
20032 panel->SetTitlePos(TGGroupFrame::kCenter);
20033 frame->AddFrame(panel);
20034
20035 TGTextButton* list=new TGTextButton(panel,"List");
20036 list->Connect("Clicked()","NcAstrolab",this,"MapList()");
20037 list->SetToolTipText("List the selected entries");
20038 TGLayoutHints* Llist=new TGLayoutHints(kLHintsCenterX,0,0,10,10);
20039 panel->AddFrame(list,Llist);
20040
20041 TGTextButton* map=new TGTextButton(panel,"Map");
20042 map->Connect("Clicked()","NcAstrolab",this,"MapDraw()");
20043 map->SetToolTipText("Display the selected entries");
20044 TGLayoutHints* Lmap=new TGLayoutHints(kLHintsCenterX,0,0,10,10);
20045 panel->AddFrame(map,Lmap);
20046
20047 TGTextButton* close=new TGTextButton(panel,"Close");
20048 close->Connect("Clicked()","NcAstrolab",this,"MapClose()");
20049 close->SetToolTipText("Close this panel window");
20050 TGLayoutHints* Lclose=new TGLayoutHints(kLHintsCenterX,0,0,10,10);
20051 panel->AddFrame(close,Lclose);
20052
20053 TGTextButton* exit=new TGTextButton(panel,"Exit");
20054 exit->Connect("Clicked()","NcAstrolab",this,"MapExit()");
20055 exit->SetToolTipText("Exit this ROOT session");
20056 TGLayoutHints* Lexit=new TGLayoutHints(kLHintsCenterX,0,0,10,10);
20057 panel->AddFrame(exit,Lexit);
20058}
20059
20061{
20067
20068 SetMapTS(); // Set the skymap timestamp
20069
20070 fSkyMapPanel->RequestFocus();
20071
20072 Int_t type=0;
20073 if (fMapDoptions[3]) type=1;
20074 if (fMapDoptions[2] && fMapDoptions[3]) type=-1;
20075
20076 NcTimestamp* ts=&fMapTS; // User selected timestamp
20077 if (fMapLabTS) ts=0; // To get Lab timestamp notification in listings
20078
20079 Int_t j=0;
20080 if (fMapDoptions[4]) j=-1; // Individual reference timestamps
20081
20082 printf("\n");
20084}
20085
20087{
20093
20094 SetMapTS(); // Set the skymap timestamp
20095
20096 fSkyMapPanel->RequestFocus();
20097
20098 Int_t type=0;
20099 if (fMapDoptions[3]) type=1;
20100 if (fMapDoptions[2] && fMapDoptions[3]) type=-1;
20101
20102 NcTimestamp* ts=&fMapTS; // User selected timestamp
20103 if (fMapLabTS) ts=0; // To get Lab timestamp notification in listings
20104
20105 Int_t j=0;
20106 if (fMapDoptions[4]) j=-1; // Individual reference timestamps
20107
20112
20114}
20115
20117{
20123
20124 // De-activate all automatic CloseWindow() actions of the system window manager
20125 // in order to fully control it in this function
20126 fSkyMapPanel->DontCallClose();
20127
20128 // To prevent crash when the cursor is still left active in a TextEntry
20129 fSkyMapPanel->RequestFocus();
20130
20131 // Unmap the display window
20132 fSkyMapPanel->UnmapWindow();
20133}
20134
20136{
20142
20143 fSkyMapPanel->RequestFocus();
20144 fSkyMapPanel->Cleanup();
20145 gApplication->Terminate(0);
20146}
20147
20149{
20155
20156 fMapLabTS=kFALSE;
20157 Int_t imjd=0;
20158 Int_t isec=0;
20159 Int_t ins=0;
20160 Int_t ips=0;
20161
20162 if (fMapTimeType=="SysClock") // Use the system clock time
20163 {
20164 fMapTS.SetSystemTime();
20165 }
20166 else if (fMapTimeType=="Lab") // Use the Lab timestamp
20167 {
20168 fMapTS.SetMJD(fMJD,fJsec,fJns,fJps);
20169 fMapLabTS=kTRUE;
20170 }
20171 else if (fMapTimeType=="MJD") // Modified Julian Date entry
20172 {
20173 Double_t mjd=fMapDateTime.Atof();
20174 fMapTS.SetMJD(mjd);
20175 }
20176 else if (fMapTimeType=="JD") // Julian Date entry
20177 {
20178 Double_t jd=fMapDateTime.Atof();
20179 fMapTS.SetJD(jd);
20180 }
20181 else if (fMapTimeType=="TJD") // Truncated Julian Date entry
20182 {
20183 Double_t tjd=fMapDateTime.Atof();
20184 fMapTS.SetTJD(tjd);
20185 }
20186 else if (fMapTimeType=="Unix") // Unix time
20187 {
20188 Double_t val=fMapDateTime.Atof();
20189 fMapTS.SetUnixTime(val);
20190 }
20191 else
20192 {
20193 if (fMapTimeType.Contains("Name")) // Get timestamp of the specified named entry
20194 {
20195 NcSignal* sx=0;
20196 NcTimestamp* tx=0;
20197 TString name=fMapDateTime;
20198 sx=GetSignal(name,1);
20199 if (!sx) sx=GetSignal(name,0);
20200 if (sx) tx=sx->GetTimestamp();
20201 if (tx) // Stored entry was found
20202 {
20203 tx->GetMJD(imjd,isec,ins);
20204 ips=tx->GetPs();
20205 fMapTS.SetMJD(imjd,isec,ins,ips);
20206 }
20207 else
20208 {
20209 printf("\n *** No stored entry with name %-s found --> Lab TS will be used *** \n",name.Data());
20210 GetMJD(imjd,isec,ins);
20211 ips=GetPs();
20212 fMapTS.SetMJD(imjd,isec,ins,ips);
20213 fMapLabTS=kTRUE;
20214 }
20215 fMapTS.GetDayTimeString("UTC",12,0,&fMapDate,&fMapTime,kFALSE);
20216 }
20217 else // Date/Time entry
20218 {
20220 fMapDate.Remove(fMapDateTime.Index("/"),fMapDateTime.Length());
20222 fMapTime.Remove(0,fMapDateTime.Index("/")+1);
20223 }
20224
20225 // Set the timestamp according to the date/time strings
20226 fMapTS.SetUT(fMapDate,fMapTime,0);
20227 if (fMapTimeType=="UT1") fMapTS.SetUT(fMapDate,fMapTime,0,"U");
20228 if (fMapTimeType=="LMT") fMapTS.SetLT(fToffset,fMapDate,fMapTime,0);
20229 if (fMapTimeType=="GPS" || fMapTimeType=="TAI" || fMapTimeType=="TT")
20230 {
20231 fMapTS.SetTAI(fMapTimeType,fMapDate,fMapTime,0,"A",0);
20232 }
20233 }
20234
20235 // Show the new timestamp in the textbox
20236 fMapTS.GetDayTimeString("UTC",3,0,&fMapDate,&fMapTime,kFALSE);
20238 fMapDateTime+="/";
20240 fMapTSdatetime->SetText(fMapDateTime);
20241
20242 // Adapt the timestamp type for the updated text window contents
20243 if (fMapTStimetype) fMapTStimetype->Select(1,kTRUE);
20244 MapTimeType(1);
20245}
20246
20247TObject* NcAstrolab::Clone(const char* name) const
20248{
20257
20258 NcAstrolab* lab=new NcAstrolab(*this);
20259 if (name)
20260 {
20261 if (strlen(name)) lab->SetName(name);
20262 }
20263 return lab;
20264}
20265
ClassImp(NcAstrolab)
Handling of 3-vectors in various reference frames.
Definition Nc3Vector.h:15
Double_t GetX(Int_t i, TString f, TString u="rad")
void GetErrors(Double_t *e, TString f, TString u="rad") const
void SetVector(Double_t *v, TString f, TString u="rad")
virtual void Load(Nc3Vector &q)
virtual void SetZero()
Nc3Vector Cross(Nc3Vector &q) const
void SetErrors(Double_t *e, TString f, TString u="rad")
virtual Double_t GetOpeningAngle(Nc3Vector &q, TString u="rad")
void GetVector(Double_t *v, TString f, TString u="rad") const
Int_t HasErrors() const
Nc3Vector GetPrimed(TRotMatrix *m) const
Int_t HasVector() const
Nc3Vector GetUnprimed(TRotMatrix *m) const
Double_t GetNorm()
Virtual lab to provide (astro)physical parameters, treat data and relate observations with astrophysi...
Definition NcAstrolab.h:47
Double_t fMW
Definition NcAstrolab.h:372
void MapMerUc(Int_t i)
void Precess(Nc3Vector &r, NcTimestamp *ts1, NcTimestamp *ts2)
void MapEname(const char *text)
void Nutate(Nc3Vector &r, NcTimestamp *ts)
void MakeBurstRecoAngresdist(TString file, TString tree, TString name1, TString name2, TString ua, TString name3, TString ud, Double_t Emin, Double_t Emax, Int_t nbe=100, Int_t nba=1000)
Double_t fMapMerC
! The GUI entered central meridian location for the Map
Definition NcAstrolab.h:356
void ProjectMercator(Double_t l, Double_t b, Double_t &x, Double_t &y)
Double_t fMeridian
! Central meridian (in rad) for the sky display
Definition NcAstrolab.h:302
Double_t GetTargetThickness(Double_t prob, Double_t lambda) const
Double_t fMp
Definition NcAstrolab.h:370
TRotMatrix fL
Definition NcAstrolab.h:266
virtual void LabLocationPanel(TGCompositeFrame *frame)
void GetBurstBayesianPsiStatistics(TString type, Double_t nr=-1, Int_t ncut=10, Int_t ndt=2, Bool_t zcor=kFALSE, Int_t freq=0)
void MapEnterSolar()
Double_t GetCredibleInterval(TF1 pdf, Double_t p, Double_t &xlow, Double_t &xup, Int_t n=1000)
void SetRandomiser(Int_t iseed, Int_t cnt1=0, Int_t cnt2=0, NcTimestamp *ts=0)
Double_t GetLT()
Double_t GetUpperLimit(TF1 pdf, Double_t p)
Double_t fGammaW
Definition NcAstrolab.h:373
Double_t fSpeedC
Definition NcAstrolab.h:364
TH1F GetDxHistogram(TH1 *hx, Int_t nc, Double_t dxbin=-1, Double_t dxmin=-1, Double_t dxmax=-1, Int_t mode=1, Double_t fact=1)
TString fDataFrame
Definition NcAstrolab.h:405
ULong64_t fNen[2]
Definition NcAstrolab.h:257
NcSample fBurstOffAeff
Definition NcAstrolab.h:425
Double_t fMapMarkSize
! The GUI entered marker size for the Map
Definition NcAstrolab.h:358
TF1 * fPhiscfunc
Definition NcAstrolab.h:281
void HelioToGeocentric(Double_t &R, Double_t &B, Double_t &L, NcTimestamp *ts, TString Bu="deg", TString Lu="deg")
void MapMarkType(Int_t i)
Int_t GetTimeScramble(Double_t *tmin=0, Double_t *tmax=0, TF1 *frndm=0)
TRotMatrix fP
! Matrix for precession correction
Definition NcAstrolab.h:260
Double_t fHbarc2
Definition NcAstrolab.h:394
Double_t fTscmin
Definition NcAstrolab.h:269
void MapCinfo(Int_t)
void MapEb(const char *text)
Double_t fAlphaEM
Definition NcAstrolab.h:376
void MatchSignals(NcDevice &matches, Double_t da, TString au, Double_t dt, TString tu, Int_t mode=1, Int_t i1=1, Int_t i2=0, Int_t itype=0, Int_t j1=1, Int_t j2=0, Int_t jtype=1)
TF1 fBkgEprofile
Definition NcAstrolab.h:413
TString fMapEcoord
! The GUI entered coordinate system of the entry
Definition NcAstrolab.h:344
Int_t SetSolarSystem(TString name, NcTimestamp *ts, Int_t type=0)
Double_t GetLightTravelDistance(Double_t z, TString u="Mpc") const
Double_t fMapLabLocB
! The GUI entered Lab latitude
Definition NcAstrolab.h:322
Double_t fToffset
Definition NcAstrolab.h:253
TString fMapEua
! The GUI entered angular units of a
Definition NcAstrolab.h:340
Double_t fOmegaR
Definition NcAstrolab.h:386
Double_t fThetascmin
Definition NcAstrolab.h:276
Double_t fAmu
Definition NcAstrolab.h:369
Int_t fSolUpdate
Definition NcAstrolab.h:297
void SetBurstParameter(TString name, Double_t value)
void MapProj(Int_t i)
TString fBkgEmode
Definition NcAstrolab.h:411
TObjArray * fSigs
Definition NcAstrolab.h:256
Double_t fDscmin
Definition NcAstrolab.h:273
NcObjMatrix fDataNames
Definition NcAstrolab.h:407
void SmearPosition(Nc3Vector &v, Double_t sigma)
Double_t GetLightTravelTime(Double_t z) const
Int_t GetPositionScramble(Double_t *dmin=0, Double_t *dmax=0, TF1 *df=0, Double_t *thmin=0, Double_t *thmax=0, TF1 *thf=0, Double_t *phimin=0, Double_t *phimax=0, TF1 *phif=0)
void ProjectCylindrical(Double_t l, Double_t b, Double_t &x, Double_t &y)
void MapExperiment(Int_t i)
void MapMarkSize(const char *text)
TRotMatrix fG
! Matrix for conversion of equatorial to galactic coordinates
Definition NcAstrolab.h:262
Float_t fMarkerSize[4]
Definition NcAstrolab.h:307
TString fMapTime
! The GUI entered time
Definition NcAstrolab.h:329
Double_t GetBurstRecoAngres(Double_t Emin=-1, Double_t Emax=-1, Double_t Amin=0, Double_t Amax=999) const
TString fExperiment
Definition NcAstrolab.h:251
TRotMatrix fB
! The frame bias matrix for conversion of ICRS to J2000 coordinates
Definition NcAstrolab.h:258
virtual void EntriesPanel(TGCompositeFrame *frame)
TH1 * GetBurstBayesianSignalRate(Double_t p, Double_t &rlow, Double_t &rup, Int_t n=1000)
Double_t ConvertAngle(Double_t a, TString in, TString out) const
TObjArray fBurstHistos
Definition NcAstrolab.h:417
void GetBurstMaxEventCount(NcSignal *sx)
void SetNmatrix(NcTimestamp *ts)
Double_t fGn
Definition NcAstrolab.h:381
Double_t fOmegaC
Definition NcAstrolab.h:389
Double_t fHbar
Definition NcAstrolab.h:392
void ProjectHammer(Double_t l, Double_t b, Double_t &x, Double_t &y)
Double_t GetDifference(Int_t jref, TString au, Double_t &dt, TString tu, Int_t mode=1, Int_t *ia=0, Int_t *it=0)
void ListSignals(TString frame, TString mode, Int_t ndig=1, TString emode="T", Int_t nmax=10, Int_t j=-1, Int_t type=-1, NcTimestamp *ts=0, TString name="*")
Double_t GetSourceAttributes(NcSignal *s, Float_t *z=0, Float_t *T90=0)
NcPosition fLabPos
Definition NcAstrolab.h:250
TString fProj
! Projection which is currently in use
Definition NcAstrolab.h:303
Double_t GetLuminosityDistance(Double_t z, TString u="Mpc") const
NcDevice * fBurstParameters
Definition NcAstrolab.h:416
TRotMatrix fH
! Matrix for conversion of equatorial to horizontal coordinates
Definition NcAstrolab.h:265
Int_t RemoveSignal(Int_t j, Int_t type, Int_t compress)
Double_t GetBurstBackgroundEnergy(Double_t Emin=-1, Double_t Emax=-1) const
void SetLabPosition(Nc3Vector &r)
void MapLabLframeEnter()
TString fMapTimeType
! The GUI entered time type
Definition NcAstrolab.h:330
TString GetExperiment() const
void MapDoptions(Int_t i)
Double_t GetLabTimeOffset() const
void GenBurstGCNdata(Int_t n, TString name="GRB", Bool_t scale=kFALSE)
Double_t GetComovingDistance(Double_t z, TString u="Mpc") const
Double_t fNewton
Definition NcAstrolab.h:380
TH2 * fHist[2]
! Temp. histograms for the sky display
Definition NcAstrolab.h:305
TGComboBox * fMapTStimetype
! The GUI TS time type selection box
Definition NcAstrolab.h:327
TString fMapCinfo
! The GUI selected info category
Definition NcAstrolab.h:335
Double_t fTscmax
Definition NcAstrolab.h:270
void MapMerMode(Int_t i)
TArrayI * fIndices
! Storage indices of the matching reference signals
Definition NcAstrolab.h:267
TH1 * GetBurstSigmaPosdist(TString name, TString type)
TString fMapProj
! The GUI selected projection for the Map
Definition NcAstrolab.h:348
Bool_t fMapLabTS
! The GUI selection to use the Lab timestamp for the List/Map
Definition NcAstrolab.h:333
void MapEcoord(Int_t i)
void GetLocalFrame(Float_t arr[6])
void LoadInputData(Bool_t src, TString file, TString tree, Int_t date1=0, Int_t date2=0, Int_t nmax=-1, TString type="-")
NcSample fBurstSigReco
Definition NcAstrolab.h:420
Double_t fGammaZ
Definition NcAstrolab.h:375
NcSample fBurstOnReco
Definition NcAstrolab.h:418
void InitBurstHistograms(Int_t mode)
TF1 * fThetascfunc
Definition NcAstrolab.h:278
TString fMapLabLocU
! The GUI entered Lab location angular units
Definition NcAstrolab.h:323
TCanvas * fCanvas
! The canvas for the skymap
Definition NcAstrolab.h:304
Double_t fOmegaM
Definition NcAstrolab.h:385
TF1 fSigEprofile
Definition NcAstrolab.h:412
void MapDname(const char *text)
void MapIname(const char *text)
NcAstrolab(const char *name="User", const char *title="Virtual Lab for general use")
Double_t GetBurstLiMaSignificance() const
virtual void SkyMapPanel()
Int_t GetSignalIndex(TString name, Int_t type=0)
TGTextEntry * fMapTSdatetime
! The GUI TS date/time specification
Definition NcAstrolab.h:326
void MapLocb(const char *text)
TRotMatrix fN
! Matrix for nutation correction
Definition NcAstrolab.h:261
void ListBurstParameters() const
TGNumberEntryField * fMapLabLBI[3]
! The GUI number entries for the Lab location specification
Definition NcAstrolab.h:318
void MapTinfo(Int_t)
void MapEa(const char *text)
Double_t GetMeanFreePath(Double_t sigma, Double_t rho, Int_t mode) const
NcPosition GetLabPosition() const
void SetPositionScramble(Int_t mode, Double_t dmin, Double_t dmax, TF1 *df=0, Double_t thmin=0, Double_t thmax=0, TF1 *thf=0, Double_t phimin=0, Double_t phimax=0, TF1 *phif=0)
void InitDataNames(Int_t dir, TString frame, TString mode="J")
Double_t GetHubbleParameter(Double_t z, TString u="Mpc") const
void MapEtype(Int_t i)
void LoadAeffData(TString file, TString hist)
Int_t fMapMarkStyle
! The GUI selected marker style for the Map
Definition NcAstrolab.h:359
Int_t SetSourceAttributes(NcSignal *s, Double_t sigmapos, TString u, Double_t z=-999, Double_t T90=-999)
void MapUa(Int_t i)
Double_t GetMaxDt() const
void SetTimeScramble(Int_t mode, Double_t tmin, Double_t tmax, TF1 *frndm=0)
TString fMapDcoord
! The GUI selected coordinate system for the Map/List
Definition NcAstrolab.h:347
void MapUinfo(Int_t)
void MapDcoord(Int_t i)
Double_t fPhiscmin
Definition NcAstrolab.h:279
Double_t fPhiscmax
Definition NcAstrolab.h:280
void SetPmatrix(NcTimestamp *ts)
void MakeBurstNuCountProfile(TString mode)
Double_t GetLAST()
Double_t fMapEb
! The GUI entered b coordinate of an entry
Definition NcAstrolab.h:341
TString fMapDate
! The GUI entered date
Definition NcAstrolab.h:328
TF1 GetSignalRatePDF(Double_t Non, Double_t Ton, Double_t Noff, Double_t Toff, Double_t Ra=1, Double_t Re=1, Double_t smax=-1, Double_t bmax=-1, Double_t prec=709)
Double_t fDscmax
Definition NcAstrolab.h:274
Double_t fMapLabLocL
! The GUI entered Lab longitude
Definition NcAstrolab.h:321
Int_t fMapMarkType
! The GUI selected entry type to apply the marker attributes on
Definition NcAstrolab.h:361
void MapMarkStyle(Int_t i)
Double_t fPc
Definition NcAstrolab.h:383
Double_t fMn
Definition NcAstrolab.h:371
void Project(Double_t l, Double_t b, TString proj, Double_t &x, Double_t &y)
Double_t fQe
Definition NcAstrolab.h:365
void MapUloc(Int_t i)
void SetBmatrix()
NcRandom * fRan
Definition NcAstrolab.h:282
void MapDateTime(const char *text)
Double_t GetBurstTotalFluence(Double_t nsig, TString str)
Double_t fThetascmax
Definition NcAstrolab.h:277
TString fMapDmode
! The GUI selected coordinate system mode for the Map/List
Definition NcAstrolab.h:349
Double_t GetShieldingThickness(Double_t prob, Double_t lambda) const
TString fMapEub
! The GUI entered angular units of b
Definition NcAstrolab.h:342
void MapMarkColor(Int_t i)
Double_t GetBackgroundRateProb(Double_t *vars, Double_t *pars)
Double_t GetInteractionProbability(Double_t x, Double_t lambda) const
void MakeBurstSigmaPosdist(TString file, TString tree, TString name, TString u, Int_t nb=900, Float_t xmin=0, Float_t xmax=90)
void MapNdigs(const char *text)
Int_t GetNRefSignals(Int_t mode=0) const
TH1F GetDifHistogram(TH1 *hin, Int_t mode, TString s="", TF1 *f=0) const
Int_t fMapEtype
! The GUI entered entry type
Definition NcAstrolab.h:343
TGComboBox * fMapLabU
! The GUI Lab location angular unit selection box
Definition NcAstrolab.h:319
Double_t fAu
Definition NcAstrolab.h:382
NcSample fBurstOffMatch
Definition NcAstrolab.h:423
void MapLocEnter()
void SetDataNames(TString obsname, TString varname, TString units="1", TString func="none")
TString fMapDname
! The GUI entered name pattern for entries to be shown in the Map/List
Definition NcAstrolab.h:353
TGNumberEntryField * fMapLabLframe[6]
! The GUI number entries for the local frame specification
Definition NcAstrolab.h:334
Double_t fOmegaL
Definition NcAstrolab.h:387
void GenBurstSignals()
void SetGmatrix(TString mode)
Double_t GetNeutrinoXsection(Int_t mode, Int_t type, Double_t egev, Double_t xscale=1, Double_t *eprimgev=0, Double_t *alpha=0) const
TH1 * GetBurstT90dist(TString name, TString type)
Double_t fMe
Definition NcAstrolab.h:366
NcDevice * GetBurstParameters()
void ListBurstHistograms() const
void MakeBurstEnergydist(Int_t mode, TString file, TString tree, TString name1, TString name2, TString u, Int_t nb=1000)
void SetLT(Int_t y, Int_t m, Int_t d, Int_t hh, Int_t mm, Int_t ss, Int_t ns=0, Int_t ps=0)
void MapSolar(Int_t i)
void MapLocl(const char *text)
Int_t fLabId
Definition NcAstrolab.h:252
void MakeBurstDataStats(Int_t mode, Int_t nmugrb=0)
void SetCentralMeridian(Int_t mode=0, Double_t phi=0, TString u="deg")
Int_t fGal
! Type indicator for fG values (0=uninitialised 1=B1950 2=J2000)
Definition NcAstrolab.h:263
NcSample fBurstSignal
Definition NcAstrolab.h:421
Int_t fMapLabId
! The GUI entered Lab detector Id
Definition NcAstrolab.h:325
void ListBurstSignalStats(Double_t rate, Int_t mode, TString str="-")
void SetEmatrix(NcTimestamp *ts)
Int_t RemoveRefSignal(Int_t j, Int_t compress)
Int_t fMapMarkColor
! The GUI selected marker color for the Map
Definition NcAstrolab.h:360
void MakeBurstT90dist(TString file, TString tree, TString name, Int_t nb=50, Float_t xmin=-5, Float_t xmax=5)
void MapRemoveSolar()
void MapUb(Int_t i)
void DisplaySignal(TString frame, TString mode, NcTimestamp *ts, Int_t j=-1, TString proj="ham", Int_t clr=0, TString name="")
virtual void TimestampPanel(TGCompositeFrame *frame)
void SetHmatrix(NcTimestamp *ts)
void PrintSignal(TString frame, TString mode, NcTimestamp *ts, Int_t ndig, Int_t jref=0, TString emode="T", Int_t type=0, Bool_t align=kFALSE)
void SetLabTimeOffset(Double_t dt)
TH1F GetCumulHistogram(TH1 *h, TString name, TString mode="F") const
virtual void MapListOptionsPanel(TGCompositeFrame *frame)
TObjArray * fMarkers
! Temp. array to hold the markers for the signal display
Definition NcAstrolab.h:306
TString fMapDateTime
! The GUI entered datetime
Definition NcAstrolab.h:331
Double_t GetSolidAngle(Double_t thetamin, Double_t thetamax, TString tu, Double_t phimin, Double_t phimax, TString pu) const
void SetMarkerColor(Int_t color, Int_t type)
Int_t fMapNdigs
! The GUI selected number of digits for the List output
Definition NcAstrolab.h:352
TRotMatrix fE
! Matrix for conversion of equatorial to ecliptic coordinates
Definition NcAstrolab.h:264
Double_t GetProperDistance(Double_t z, TString u="Mpc", Int_t t=1) const
TString fMapIname
! The GUI selected entry name for the info
Definition NcAstrolab.h:338
Double_t fMapEa
! The GUI entered a coordinate of an entry
Definition NcAstrolab.h:339
Double_t fFermi
Definition NcAstrolab.h:377
Double_t fAxes[6]
Definition NcAstrolab.h:254
Bool_t fMapSolar[10]
! The GUI selection of solar system objects
Definition NcAstrolab.h:354
TF1 * fTscfunc
Definition NcAstrolab.h:271
void GetBurstChi2Statistics(TString type, Int_t ndt=2, Bool_t zcor=kFALSE)
Double_t GetBurstSignalEnergy(Double_t Emin=-1, Double_t Emax=-1) const
void MapLocId(const char *text)
Bool_t fMapDoptions[5]
! The GUI Map/List options (histo, clr, ref, meas, refTS)
Definition NcAstrolab.h:350
Int_t fRscmode
Definition NcAstrolab.h:272
Int_t RemoveSignals(TString name, Int_t type, Int_t compress)
void SetPhysicalParameter(TString name, Double_t value)
Double_t fHubble
Definition NcAstrolab.h:384
Double_t fMmu
Definition NcAstrolab.h:367
void MatchBurstData(NcDevice &matches, Int_t i1=1, Int_t i2=0, Int_t itype=0, Int_t j1=1, Int_t j2=0, Int_t jtype=1)
void ShiftPosition(Nc3Vector &v, Double_t angle)
void MakeBurstZdist(TString file, TString tree, TString name, Int_t nb=200, Float_t zmin=0, Float_t zmax=20)
TString fDataMode
Definition NcAstrolab.h:406
TArrayI * MatchRefSignal(Double_t da, TString au, Double_t dt, TString tu, Int_t mode=1)
NcSample fBurstSigAeff
Definition NcAstrolab.h:426
void WriteBurstHistograms(TString filename)
void GeoToHeliocentric(Double_t &R, Double_t &B, Double_t &L, NcTimestamp *ts, TString Bu="deg", TString Lu="deg")
Double_t GetSignalRateProb(Double_t *vars, Double_t *pars)
Double_t GetNuclearMass(Int_t Z, Int_t N, Int_t mode=1) const
Int_t fTscmode
Definition NcAstrolab.h:268
virtual void InfoPanel(TGCompositeFrame *frame)
void BurstCompensate(Int_t &nmugrb)
void SetLocalFrame(Double_t t1, Double_t p1, Double_t t2, Double_t p2, Double_t t3, Double_t p3)
void Data(Int_t mode=1, TString u="deg", Bool_t utc=kTRUE)
void ProjectAitoff(Double_t l, Double_t b, Double_t &x, Double_t &y)
void SetMarkerSize(Float_t size, Int_t type)
TF1 * fDscfunc
Definition NcAstrolab.h:275
void DisplaySignals(TString frame, TString mode, NcTimestamp *ts, TString proj="ham", Int_t clr=0, Int_t nmax=-1, Int_t j=-1, Int_t type=-1, TString name="*")
NcSignal * GetSignal(Double_t &d, Double_t &a, TString au, Double_t &b, TString bu, TString frame, NcTimestamp *ts, Int_t jref, TString mode="T", Int_t type=0)
void ListDataNames()
virtual void LabLocalFramePanel(TGCompositeFrame *frame)
TString fMapMerUc
! The GUI selected angular units for the central meridian location
Definition NcAstrolab.h:357
NcSample fBurstOffReco
Definition NcAstrolab.h:422
TF1 * fNuAngle
Definition NcAstrolab.h:397
Int_t fMarkerStyle[4]
Definition NcAstrolab.h:308
Int_t fUsMeridian
Definition NcAstrolab.h:301
void SetExperiment(TString name, Int_t id=0)
TH1 * GetBurstZdist(TString name, TString type)
TString fMapUinfo
! The GUI selected angular units for the Lab info
Definition NcAstrolab.h:337
Double_t fMaxDt
Definition NcAstrolab.h:283
TString fMapEname
! The GUI entered name of the entry
Definition NcAstrolab.h:346
Int_t GetLabDetectorId() const
Double_t fMtau
Definition NcAstrolab.h:368
Double_t GetPhysicalParameter(TString name) const
virtual TObject * Clone(const char *name="") const
Double_t GetNeutrinoAngle(Double_t E, TString u, Int_t mode, TF1 *f=0)
Double_t fOmegaB
Definition NcAstrolab.h:388
TGMainFrame * fSkyMapPanel
! The main frame for the SkyMapPanel GUI
Definition NcAstrolab.h:317
Int_t GetNsignals(Int_t type, Int_t mode=0) const
Double_t fPlanck
Definition NcAstrolab.h:378
Double_t fBoltz
Definition NcAstrolab.h:379
void SetMarkerStyle(Int_t style, Int_t type)
NcSignal * SetSignal(Double_t d, Double_t a, TString au, Double_t b, TString bu, TString frame, NcTimestamp *ts, Int_t jref, TString mode="T", TString name="", Int_t type=0)
Int_t fDataDir
Definition NcAstrolab.h:404
Double_t GetLMST()
Int_t fMapMerMode
! The GUI selected meridian orientation for the Map
Definition NcAstrolab.h:355
void PrintAngle(Double_t a, TString in, TString out, Int_t ndig=1, Bool_t align=kFALSE) const
Int_t fMarkerColor[4]
Definition NcAstrolab.h:309
void MapMerC(const char *text)
Int_t fMapTinfo
! The GUI selected mode for the timestamp info
Definition NcAstrolab.h:336
void SetMaxDt(Double_t s)
TH1F GetLogHistogram(TH1 *hin, Int_t mode, TString s="") const
NcTimestamp fMapTS
! The GUI entered timestamp to be used for the List/Map
Definition NcAstrolab.h:332
Double_t GetPhysicalDistance(Double_t z, TString u="Mpc", Int_t t=1) const
void MapTimeType(Int_t i)
Double_t KolmogorovTest(TString mode, TH1 *h1, TH1 *h2=0, TF1 *pdf=0, Double_t nr=1000, TH1F *ksh=0, Int_t ncut=0, Double_t *nrx=0, Int_t mark=1)
TGComboBox * fMapLabE
! The GUI Lab experiment site selection box
Definition NcAstrolab.h:320
virtual void CommandPanel(TGCompositeFrame *frame)
Double_t GetSurvivalProbability(Double_t x, Double_t lambda) const
NcSample fBurstOnAeff
Definition NcAstrolab.h:424
Double_t GetHourAngle(TString mode, NcTimestamp *ts, Int_t jref=0, Int_t type=0)
Double_t GetRadiationLength(Double_t Z, Double_t A, Double_t rho=-1) const
Int_t fMapNmax
! The GUI selected max. number of signals of each type to Map/List
Definition NcAstrolab.h:351
Int_t fBias
! Initialisation flag for fB values (0=uninitialised 1=initialised)
Definition NcAstrolab.h:259
void RandomPosition(Nc3Vector &v, Double_t thetamin, Double_t thetamax, Double_t phimin, Double_t phimax)
TObjArray * fRefs
Definition NcAstrolab.h:255
TString fMapLabExpName
! The GUI entered Lab experimental site
Definition NcAstrolab.h:324
TF1 GetBackgroundRatePDF(Double_t Noff, Double_t Toff, Double_t bmax=-1, Double_t prec=709)
TString fMapEmode
! The GUI entered coordinate system mode of the entry
Definition NcAstrolab.h:345
NcRandom * GetRandomiser(Int_t &iseed, Int_t &cnt1, Int_t &cnt2) const
void GetBurstDtDistributions(Int_t ndt, TH1F &hisdtOn, TF1 &pdfdtOn, TH1F &hisdtOff, TF1 &pdfdtOff, Bool_t zcor)
void MapNmax(const char *text)
Double_t fMZ
Definition NcAstrolab.h:374
TH1F GetCountsHistogram(TF1 &spec, Int_t nbins, Double_t xmin, Double_t xmax, Int_t mode, TString s="") const
virtual ~NcAstrolab()
NcSample fBurstOnMatch
Definition NcAstrolab.h:419
Double_t fHbarc
Definition NcAstrolab.h:393
TString fSigEmode
Definition NcAstrolab.h:410
Double_t GetSeparation(TString name1, TString name2, TString au, Double_t *dt=0, TString tu="s", Int_t mode=1, Double_t *diftheta=0, Double_t *difphi=0)
void AddNamedSlot(TString s)
Int_t GetSlotIndex(TString name, Int_t opt=0) const
(Bayesian) Block treatment of sequential data.
Definition NcBlocks.h:17
Int_t Rebin(TH1 *hin, TH1 *hout, Bool_t scale, Int_t nbins=0, Double_t xmin=0, Double_t xmax=-1)
Int_t Divide(TH1 *h1, TH1 *h2, TH1 *hout, Bool_t scale, Double_t c, Double_t d=0)
Double_t GetBlocks(TH1 *hin, Double_t fpr, TH1 *hout, Int_t ntrig=0)
Definition NcBlocks.cxx:523
Signal (Hit) handling of a generic device.
Definition NcDevice.h:14
void AddHit(NcSignal &s)
Definition NcDevice.cxx:336
void SetHitCopy(Int_t j)
Definition NcDevice.cxx:237
virtual TObject * Clone(const char *name="") const
Int_t GetNhits() const
Definition NcDevice.cxx:437
NcSignal * GetHit(Int_t j) const
Definition NcDevice.cxx:489
virtual void Reset(Int_t mode=0)
Definition NcDevice.cxx:222
Various mathematical tools for scientific analysis.
Definition NcMath.h:26
Double_t PsiValue(Int_t m, Int_t *n, Double_t *p=0, Int_t f=0) const
Definition NcMath.cxx:2829
Double_t LnGamma(Double_t z) const
Definition NcMath.cxx:193
Double_t Chi2Pvalue(Double_t chi2, Int_t ndf, Int_t sides=0, Int_t sigma=0, Int_t mode=1) const
Definition NcMath.cxx:1784
Double_t LiMaSignificance(Double_t Non, Double_t Ton, Double_t Noff, Double_t Toff, Double_t Ra=1, Double_t Re=1) const
Definition NcMath.cxx:4172
Double_t Gamma(Double_t z) const
Definition NcMath.cxx:121
Double_t PsiExtreme(Double_t n, Int_t m, Double_t *p=0, Int_t k=0) const
Definition NcMath.cxx:3138
Double_t PsiPvalue(Double_t psi0, Double_t nr, Double_t n, Int_t m, Double_t *p=0, Int_t f=0, Double_t *na=0, TH1F *psih=0, Int_t ncut=0, Double_t *nrx=0, Int_t mark=1)
Definition NcMath.cxx:3528
TF1 PoissonDtDist(Double_t r, Int_t n) const
Definition NcMath.cxx:1260
Double_t Chi2Value(Int_t m, Int_t *n, Double_t *p=0, Int_t *ndf=0) const
Definition NcMath.cxx:3867
Handling of positions (with timestamps) in various reference frames.
Definition NcPosition.h:18
void GetPosition(Double_t *r, TString f, TString u="rad", Float_t s=-1) const
void SetPosition(Double_t *r, TString f, TString u="rad")
NcTimestamp * GetTimestamp()
void SetTimestamp(NcTimestamp &t)
Generate universal random numbers and sequences on all common machines.
Definition NcRandom.h:16
Sampling and statistics tools for various multi-dimensional data samples.
Definition NcSample.h:28
Int_t GetN() const
Double_t GetMedian(Int_t i)
void Enter(Double_t x)
Definition NcSample.cxx:357
void SetStoreMode(Int_t mode=1, Int_t nmax=0, Int_t i=0)
Double_t GetEntry(Int_t i, Int_t j, Int_t mode=0, Int_t k=0)
Generic handling of (extrapolated) detector signals.
Definition NcSignal.h:23
virtual void Reset(Int_t mode=0)
Definition NcSignal.cxx:334
virtual void SetSignal(Double_t sig, Int_t j=1)
Definition NcSignal.cxx:516
virtual Float_t GetSignal(Int_t j=1, Int_t mode=0) const
Definition NcSignal.cxx:651
virtual void Data(TString f="car", TString u="rad") const
Definition NcSignal.cxx:959
Double_t GetEpoch(TString mode)
Double_t GetMJD(Int_t y, Int_t m, Int_t d, Int_t hh, Int_t mm, Int_t ss, Int_t ns) const
void SetLT(Double_t dt, Int_t y, Int_t m, Int_t d, Int_t hh, Int_t mm, Int_t ss, Int_t ns=0, Int_t ps=0, TString utc="A", Int_t leap=0, Double_t dut=0)
Double_t GetJD(Int_t y, Int_t m, Int_t d, Int_t hh, Int_t mm, Int_t ss, Int_t ns) const
void GetUT(Int_t &hh, Int_t &mm, Int_t &ss, Int_t &ns, Int_t &ps)
TString GetDayTimeString(TString mode, Int_t ndig=0, Double_t offset=0, TString *date=0, TString *time=0, Bool_t full=kTRUE)
Double_t Almanac(Double_t *dpsi=0, Double_t *deps=0, Double_t *eps=0, Double_t *dl=0, TString name="", Double_t *el=0, Double_t *eb=0, Double_t *dr=0, Double_t *value=0, Int_t j=0)
Double_t GetLMST(Double_t offset)
Double_t GetMJD()
Int_t GetPs() const
Double_t GetLT(Double_t offset)
void GetGMST(Int_t &hh, Int_t &mm, Int_t &ss, Int_t &ns, Int_t &ps)
void SetEpoch(Double_t e, TString mode, TString utc="U", Int_t leap=0, Double_t dut=0)
Double_t GetGAST()
void SetUT(Int_t y, Int_t m, Int_t d, Int_t hh, Int_t mm, Int_t ss, Int_t ns=0, Int_t ps=0, TString utc="A", Int_t leap=0, Double_t dut=0)
void PrintTime(Double_t h, Int_t ndig=1) const
Double_t GetLAST(Double_t offset)
TTree * LoadUTCparameterFiles(TString leapfile="$(NCFS)/IERS/leap.txt", TString dutfile="$(NCFS)/IERS/dut.txt")
void SetTJD(Int_t tjd, Int_t sec, Int_t ns, Int_t ps=0, TString utc="U", Int_t leap=0, Double_t dut=0)
void SetMJD(Int_t mjd, Int_t sec, Int_t ns, Int_t ps=0, TString utc="U", Int_t leap=0, Double_t dut=0)
void SetJD(Int_t jd, Int_t sec, Int_t ns, Int_t ps=0, TString utc="U", Int_t leap=0, Double_t dut=0)
Double_t GetUnixTime()
void Add(Int_t d, Int_t s, Int_t ns, Int_t ps=0)
void Convert(Double_t date, Int_t &days, Int_t &secs, Int_t &ns) const
Int_t GetDifference(NcTimestamp *t, Int_t &days, Int_t &sec, Int_t &ns, Int_t &ps, TString type="UT")
void AddSec(Double_t seconds)
void Date(Int_t mode=3, Double_t offset=0)