00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TargetModule.h"
00013
00014 #include "StripHist.h"
00015
00016 #include <JobControl/JobCModuleRegistry.h>
00017 #include <JobControl/JobCResult.h>
00018 #include <MessageService/MsgService.h>
00019
00020 #include <RawData/RawRecord.h>
00021 #include <RawData/RawBeamMonBlock.h>
00022 #include <RawData/RawBeamData.h>
00023
00024 #include <Conventions/Munits.h>
00025
00026 #include <BeamDataUtil/BDTarget.h>
00027 #include <BeamDataUtil/BDSwicCalibrator.h>
00028
00029 #include <TGraph.h>
00030 #include <TGaxis.h>
00031 #include <TCanvas.h>
00032 #include <TLatex.h>
00033 #include <TEllipse.h>
00034 #include <TBox.h>
00035
00036
00037
00038 #include <cmath>
00039
00040 #define minimum(a,b) ((a) > (b) ? (b) : (a))
00041 #define maximum(a,b) ((a) > (b) ? (a) : (b))
00042
00043 using namespace std;
00044
00045 CVSID("$Id: TargetModule.cxx,v 1.14 2006/05/27 07:28:39 rhatcher Exp $");
00046 JOBMODULE(TargetModule,"MonTgt","Target quantities related for Monitoring");
00047
00048 TargetModule::TargetModule()
00049 {
00050 StripHist *sh1 = new StripHist("Beam Size H","Beam Size Red=Horizontal Blue=Vertical");
00051 StripHist *sh5 = new StripHist("Beam Size V","Beam Size Red=Horizontal Blue=Vertical");
00052 StripHist *sh2 = new StripHist("Fraction Target","The % of the beam that hit the target");
00053 StripHist *sh3 = new StripHist("Fraction Baffle","The % of the beam that hit the baffle");
00054 StripHist *sh4 = new StripHist("Integral Flux NuMI","Integral flux of the beam in 10^{12} units Red=NuMI Blue=Target");
00055 StripHist *sh6 = new StripHist("Integral Flux Tgt","Integral flux of the beam in 10^{12} units Red=NuMI Blue=Target");
00056
00057 TH2F *BeamParameters = new TH2F("Beam Parameters","Red Contours Represent 1,2,3 #sigma of Beam",10,-10,10,10,-10,10);
00058
00059 BeamParameters->GetXaxis()->SetTitle("X (mm)");
00060 BeamParameters->GetYaxis()->SetTitle("Y (mm)");
00061 BeamParameters->GetXaxis()->CenterTitle();
00062 BeamParameters->GetYaxis()->CenterTitle();
00063
00064 sh1->SetStripRange(1*Munits::day);
00065 sh2->SetStripRange(1*Munits::day);
00066 sh3->SetStripRange(1*Munits::day);
00067 sh4->SetStripRange(1*Munits::day);
00068 sh5->SetStripRange(1*Munits::day);
00069 sh6->SetStripRange(1*Munits::day);
00070
00071 sh1->SetLineColor(2);
00072 sh5->SetLineColor(4);
00073 sh4->SetLineColor(2);
00074 sh6->SetLineColor(4);
00075
00076 sh1->SetGraphYTitle("Beam Size (mm)");
00077 sh5->SetGraphYTitle("Beam Size (mm)");
00078 sh2->SetGraphYTitle("Fraction on Target (%)");
00079 sh3->SetGraphYTitle("Fraction on Baffle (%)");
00080 sh4->SetGraphYTitle("Integral Flux (10^{12} protons)");
00081 sh6->SetGraphYTitle("Integral Flux (10^{12} protons)");
00082
00083 fStripHist["Beam Size H"] = sh1;
00084 fStripHist["Beam Size V"] = sh5;
00085 fStripHist["Fraction Target"] = sh2;
00086 fStripHist["Fraction Baffle"] = sh3;
00087 fStripHist["Integral Flux NuMI"] = sh4;
00088 fStripHist["Integral Flux Tgt"] = sh6;
00089
00090 fTH2F["Beam Parameters"] = BeamParameters;
00091 }
00092
00093 TargetModule::~TargetModule()
00094 {
00095
00096 }
00097
00098 void TargetModule::BeginJob()
00099 {
00100 HistMan hm = this->GetHistMan();
00101
00102 StripHist *sh1 = fStripHist["Beam Size H"];
00103 StripHist *sh5 = fStripHist["Beam Size V"];
00104
00105 TCanvas* canvas1 = new TCanvas("Beam Size","Beam Size",500,400);
00106
00107 sh1->DrawStrip("AL");
00108 sh5->DrawStrip("LP");
00109
00110 hm.Adopt("Target",canvas1);
00111
00112 StripHist *sh2 = fStripHist["Fraction Target"];
00113
00114 TCanvas *canvas2 = new TCanvas("Fraction Beam on Target",sh2->GetHist().GetTitle(),500,400);
00115
00116 sh2->DrawStrip("AL");
00117
00118 hm.Adopt("Target",canvas2);
00119
00120 StripHist *sh3 = fStripHist["Fraction Baffle"];
00121
00122 TCanvas *canvas3 = new TCanvas("Fraction Beam on Baffle",sh3->GetHist().GetTitle(), 500,400);
00123
00124 sh3->DrawStrip("AL");
00125
00126 hm.Adopt("Target",canvas3);
00127
00128 StripHist *sh4 = fStripHist["Integral Flux NuMI"];
00129 StripHist *sh6 = fStripHist["Integral Flux Tgt"];
00130
00131 TCanvas *canvas4 = new TCanvas("Integral Flux","Integral Flux",500,400);
00132
00133 sh4->DrawStrip("AL");
00134 sh6->DrawStrip("LP");
00135
00136 hm.Adopt("Target",canvas4);
00137
00138
00139
00140 TCanvas *canvas5 = new TCanvas("Target Summary Canvas","Target Summary Canvas",600,600);
00141 canvas5->Divide(2,3);
00142 canvas5->cd(1);
00143
00144 canvas5->cd(2);
00145 sh1->DrawStrip("AL");
00146 sh5->DrawStrip("LP");
00147 canvas5->cd(3);
00148
00149 canvas5->cd(4);
00150 sh2->DrawStrip("AL");
00151 canvas5->cd(5);
00152 sh4->DrawStrip("AL");
00153 sh6->DrawStrip("LP");
00154 canvas5->cd(6);
00155 sh3->DrawStrip("AL");
00156
00157 hm.Adopt("Summary Canvases",canvas5);
00158
00159 }
00160
00161 static double approx_gaussian(double x, double sigma)
00162 {
00163
00164 const double sqrt2 = sqrt(2.0);
00165
00166 return 0.5 - 0.5 * ((sigma * sqrt2) / (3.14159 * 2.0)) * exp(-(x) / (sqrt2 * sigma));
00167 }
00168
00169 static double percentageOnTarget(double x, double y, double sigmax, double sigmay)
00170 {
00171 if( (pow(x+1.5,2) + pow(y-1.0,2)) < 5.5 && x > -4.7 && x < 1.7) {
00172 double answerx = approx_gaussian(1.7, sigmax) + approx_gaussian(4.7, sigmax);
00173 double miny = sqrt(5.5-pow(x+1.5,2))+1.0;
00174 double maxy = sqrt(5.5-pow(x+1.5,2))+1.0;
00175 double answery = approx_gaussian(miny, sigmay) + approx_gaussian(maxy, sigmay);
00176 return answerx * answery;
00177 } else {
00178 return 0.0;
00179 }
00180 }
00181
00182 static double percentageOnBaffle(double percentage_on_target)
00183 {
00184 if(percentage_on_target < 1.0) {
00185 return 1.0 - percentage_on_target;
00186 } else {
00187 return 0.0;
00188 }
00189 }
00190
00191 void TargetModule::Fill(const RawBeamMonHeaderBlock& head, const RawBeamMonBlock& block)
00192 {
00193 MSG("BD",Msg::kDebug) << "Starting TargetModule::Fill" << endl;
00194
00195
00196
00197 const RawBeamData *Emtgths = block["E:MTGTHS"];
00198 const RawBeamData *Emtgtvs = block["E:MTGTVS"];
00199 const RawBeamData *Ehp121 = block["E:HP121"];
00200 const RawBeamData *Ehptgt = block["E:HPTGT"];
00201 const RawBeamData *Evp121 = block["E:VP121"];
00202 const RawBeamData *Evptgt = block["E:VPTGT"];
00203 const RawBeamData *Etortgt = block["E:TORTGT"];
00204 const RawBeamData *Etrtgtd = block["E:TRTGTD"];
00205
00206
00207
00208
00209 if(!Emtgths || !Emtgtvs || !Ehp121 || !Ehptgt || !Evp121 || !Evptgt || !Etortgt || !Etrtgtd) {
00210 MSG("BD",Msg::kDebug) << "Do not have the devices we need!" << endl;
00211 if(!Emtgths) MSG("BD",Msg::kDebug) << " No MTGTHS" << endl;
00212 if(!Emtgtvs) MSG("BD",Msg::kDebug) << " No MTGTVS" << endl;
00213 if(!Ehp121) MSG("BD",Msg::kDebug) << " No HP121" << endl;
00214 if(!Ehptgt) MSG("BD",Msg::kDebug) << " No HPTGT" << endl;
00215 if(!Evp121) MSG("BD",Msg::kDebug) << " No VP121" << endl;
00216 if(!Evptgt) MSG("BD",Msg::kDebug) << " Np VPTGT" << endl;
00217 if(!Etortgt) MSG("BD",Msg::kDebug) << " No TORTGT" << endl;
00218 if(!Etrtgtd) MSG("BD",Msg::kDebug) << " No TRTGTD" << endl;
00219 return;
00220 }
00221
00222 if(!(Emtgths -> GetDataLength() &&
00223 Emtgtvs -> GetDataLength() &&
00224 Ehp121 -> GetDataLength() &&
00225 Ehptgt -> GetDataLength() &&
00226 Evp121 -> GetDataLength() &&
00227 Evptgt -> GetDataLength() &&
00228 Etortgt -> GetDataLength() &&
00229 Etrtgtd -> GetDataLength()))
00230 return;
00231
00232
00233 StripHist* sh1 = fStripHist["Beam Size H"];
00234 StripHist* sh5 = fStripHist["Beam Size V"];
00235 StripHist* sh2 = fStripHist["Fraction Target"];
00236 StripHist* sh3 = fStripHist["Fraction Baffle"];
00237 StripHist* sh4 = fStripHist["Integral Flux NuMI"];
00238 StripHist *sh6 = fStripHist["Integral Flux Tgt"];
00239
00240 TH2F *th1 = fTH2F["Beam Parameters"];
00241
00242 double sigmah = Emtgths->GetData()[0];
00243 double sigmav = Emtgtvs->GetData()[0];
00244 double dae = Etortgt->GetSeconds() + 1.0e-6*Etortgt->GetMsecs();
00245 double hp121 = Ehp121->GetData()[0];
00246 double hptgt = Ehptgt->GetData()[0];
00247 double vp121 = Evp121->GetData()[0];
00248 double vptgt = Evptgt->GetData()[0];
00249 double P2tgt = Etrtgtd->GetData()[0];
00250 double pos = 1168.04;
00251
00252 if(P2tgt < 0.1) {
00253
00254 return;
00255 }
00256
00257 double X = hptgt + (((hptgt - hp121) / (1134.9 - 1095.8)) * (pos - 1134.9));
00258 double Y = vptgt + (((vptgt - vp121) / (1135.8 - 1096.7)) * (pos - 1135.8));
00259
00260 MSG("BD",Msg::kDebug) << "Beam Pos : X=" << X << " +/- " << sigmav << " Y=" << Y << " +/- " << sigmah << endl;
00261 MSG("BD",Msg::kDebug) << " Also, hptgt=" << hptgt << " : vptgt=" << vptgt << " : hp121=" << hp121 << " : vp121=" << vp121 << endl;
00262
00263
00264
00265 BDTarget *target = new BDTarget();
00266 target->SetSpill(head, block);
00267 double X2 = 0.0, Y2 = 0.0, sigmav2 = 0.0, sigmah2 = 0.0;
00268 int blah = 0;
00269 blah = target->ProfileProjection(X2,Y2,sigmav2,sigmah2);
00270 MSG("BD",Msg::kDebug) << "Beam Pos : X2=" << X2<< " +/- " << sigmav2 << " Y2=" << Y2 << " +/- " << sigmah2
00271 << " and blah=" << blah << endl;
00272
00273
00274 sh1->Fill(dae, sigmah);
00275 sh5->Fill(dae, sigmav);
00276
00277 double min1 = 0.0, max1 = 0.0;
00278
00279 RangeFinder(sh1, sh5, min1, max1);
00280
00281 sh1->GetStrip().GetYaxis()->SetRangeUser(min1, max1);
00282 sh5->GetStrip().GetYaxis()->SetRangeUser(min1, max1);
00283
00284 double PerOnTarget = percentageOnTarget(X,Y,sigmav,sigmah);
00285 double PerOnBaffle = percentageOnBaffle(PerOnTarget);
00286
00287 sh2->Fill(dae, PerOnTarget*100.0);
00288 sh3->Fill(dae, PerOnBaffle*100.0);
00289
00290 double min2 = 0.0, max2 = 0.0;
00291
00292 RangeFinder(sh2, sh3, min2, max2);
00293
00294 sh2->GetStrip().GetYaxis()->SetRangeUser(min2, max2);
00295 sh3->GetStrip().GetYaxis()->SetRangeUser(min2, max2);
00296
00297 HistMan hm = this->GetHistMan();
00298 TCanvas *can = (TCanvas*) hm.GetObject("Summary Canvases/Target Summary Canvas");
00299 TVirtualPad *pad = can->cd(3);
00300 pad->Clear();
00301
00302 TLatex l;
00303 l.SetTextSize(0.1);
00304 l.DrawLatex(0.3,0.8,"Beam Parameters");
00305 l.DrawLatex(0.1,0.5,Form("X=%.4f mm",X));
00306 l.DrawLatex(0.5,0.5,Form("#sigma_{X}=%.4f mm",sigmav));
00307 l.DrawLatex(0.1,0.2,Form("Y=%.4f mm",Y));
00308 l.DrawLatex(0.5,0.2,Form("#sigma_{Y}=%.4f mm",sigmah));
00309
00310
00311 TVirtualPad *pad2 = can->cd(1);
00312 pad2->Clear();
00313 th1->SetStats(0);
00314 th1->SetTitle("");
00315 th1->Draw();
00316 TEllipse *el = new TEllipse(-1.0,1.0,5.5,5.5);
00317 el->SetLineWidth(2);
00318 el->SetLineColor(13);
00319 el->Draw();
00320 TBox *box = new TBox(-4.7, -6.5, 1.7, 8.5);
00321 box->SetFillStyle(0);
00322 box->SetLineWidth(2);
00323 box->SetLineColor(13);
00324 box->Draw();
00325
00326 TEllipse *e2 = new TEllipse(X,Y,sigmav,sigmah);
00327 e2->SetLineColor(2);
00328 e2->Draw();
00329 TEllipse *e3 = new TEllipse(X,Y,2*sigmav,2*sigmah);
00330 e3->SetLineColor(2);
00331 e3->Draw();
00332 TEllipse *e4 = new TEllipse(X,Y,3*sigmav,3*sigmah);
00333 e4->SetLineColor(2);
00334 e4->Draw();
00335
00336 pad2->Update();
00337
00338 int N = sh4->GetStrip().GetN();
00339 if(N == 0) {
00340 sh4->Fill(dae, P2tgt);
00341 sh6->Fill(dae, P2tgt * PerOnTarget);
00342 } else {
00343 double x1 = 0.0, y1 = 0.0;
00344 sh4->GetStrip().GetPoint(N-1, x1, y1);
00345 sh4->Fill(dae, (P2tgt + y1));
00346 double x2 = 0.0, y2 = 0.0;
00347 sh6->GetStrip().GetPoint(N-1, x2, y2);
00348 sh6->Fill(dae, (P2tgt * PerOnTarget + y2));
00349 }
00350
00351 double min3 = 0.0, max3 = 0.0;
00352
00353 RangeFinder(sh4, sh6, min3, max3);
00354
00355 sh4->GetStrip().GetYaxis()->SetRangeUser(min3, max3);
00356 sh6->GetStrip().GetYaxis()->SetRangeUser(min3, max3);
00357
00358
00359
00360 }
00361
00362 void TargetModule::RangeFinder(StripHist *sh1, StripHist *sh2, double &min, double &max)
00363 {
00364 double max1 = sh1->GetMax(), max2 = sh2->GetMax();
00365 double min1 = sh1->GetMin(), min2 = sh2->GetMin();
00366
00367 min = minimum(min1, min2);
00368 max = maximum(max1, max2);
00369
00370 if(fabs(min) > 0.001) {
00371 if(min < 0) {
00372 min *= 1.5;
00373 } else {
00374 min *= 0.5;
00375 }
00376 } else {
00377 min = -0.5;
00378 }
00379
00380 if(fabs(max) > 0.001) {
00381 if(max < 0) {
00382 max *= 0.5;
00383 } else {
00384 max *= 1.5;
00385 }
00386 } else {
00387 max = 0.5;
00388 }
00389
00390
00391 }