Changeset 2474 for trunk/MagicSoft
- Timestamp:
- 11/05/03 14:47:52 (21 years ago)
- Location:
- trunk/MagicSoft/Mars
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/Mars/Changelog
r2473 r2474 1 1 -*-*- END OF LINE -*-*- 2 2003/11/05: Marcos Lopez 3 4 * mmontecarlo/MMcWeightEnergySpecCalc.[h,cc] 5 - Now, if the new spectrum for the MC showers is a power law, we don't 6 convert it to a TF1 function. 7 - Changed the constructor for the case in which the new spectrum is 8 passed as a TF1 function. Now we pass the TF1 object by reference. 9 - Thanks to the suggestions of T. Bretz, added three more constructors to 10 give the possibility of passing the shape of the new spectrum in other 11 different ways. Now, if the new spectrum that you want for the MC 12 showers is different from a power law, you can especify its shape either 13 with a TF1 function, with a string (char*), or with a general C++ 14 function defined by your own. 15 - In function Reinit(): added a sanity check to prevent from dividing 16 by zero. 17 - In PreProcess(): removed an unnecessary sentence. 18 - Fixed a compiling error which appeared under gcc 3.3 19 20 * macros/weights.C 21 - addapted to show the new features introduced. 22 23 24 2 25 2003/11/05: Thomas Bretz 3 26 -
trunk/MagicSoft/Mars/macros/weights.C
r2449 r2474 23 23 \* ======================================================================== */ 24 24 25 25 26 ////////////////////////////////////////////////////////////////////////////// 26 27 // // … … 31 32 ////////////////////////////////////////////////////////////////////////////// 32 33 34 35 // -------------------------------------------------------------------------- 36 // 37 // 38 Double_t myfunction(Double_t *x, Double_t *par) 39 { 40 Double_t xx = x[0]; 41 42 return pow(xx,-2)*exp(-xx/20); 43 } 44 45 46 47 // -------------------------------------------------------------------------- 48 // 49 // 33 50 void weights(TString filename="/up1/data/Magic-MC/CameraAll/Gammas/zbin0/Gamma_zbin0_0_7_1000to1009_w0-4:4:2.root") 34 51 { … … 63 80 reader.EnableBranch("fImpact"); 64 81 65 // ------------------ 82 83 // ------------------------------------------------------------- 66 84 // 67 85 // Option 1. Just change the slope of the MC power law spectrum 68 86 // 69 //MMcWeightEnergySpecCalc wcalc(-2.0); 87 //MMcWeightEnergySpecCalc wcalc(-2.0); //<-- Uncomment me 88 70 89 // 71 // Option 2. A completely differente specturm 90 // Option 2. A completely differente specturm pass as a TF1 function 72 91 // e.g. spectrum with exponential cutoff 73 92 // 74 TF1* spec = new TF1("spectrum","pow(x,[0])*exp(-x/[1])"); 75 spec->SetParameter(0,-2.0); // Spectral index 76 spec->SetParameter(1,50); // Spectral index 77 MMcWeightEnergySpecCalc wcalc(spec); 93 //TF1 spec("spectrum","pow(x,[0])*exp(-x/[1])"); //<-- Uncomment me 94 //spec->SetParameter(0,-2.0); //<-- Uncomment me 95 //spec->SetParameter(1,50); //<-- Uncomment me 96 //MMcWeightEnergySpecCalc wcalc(spec); //<-- Uncomment me 97 98 // 99 // Option 3. A completely differente specturm pass as a cahr* 100 // 101 //char* func = "pow(x,-2)"; //<-- Uncomment me 102 //MMcWeightEnergySpecCalc wcalc(func); //<-- Uncomment me 103 104 // 105 // Option 4. A completely differente specturm pass as a c++ function 106 // 107 MMcWeightEnergySpecCalc wcalc((void*)myfunction); //<-- Uncomment me 108 // 109 //------------------------------------------------------------- 110 78 111 79 112 MFillH hfill(&h1,"MMcEvt"); 80 113 MFillH hfill2(&h2,"MMcEvt"); 81 114 hfill2.SetWeight("MWeight"); 82 //83 //------------------84 115 85 116 tasklist.AddToList(&reader); … … 115 146 hist1->DrawClone(); 116 147 hist2->DrawClone("same"); 148 117 149 } 118 150 -
trunk/MagicSoft/Mars/mmontecarlo/MMcWeightEnergySpecCalc.cc
r2448 r2474 25 25 ////////////////////////////////////////////////////////////////////////////// 26 26 // 27 // M WeightEnergySlopeCalc27 // MMcWeightEnergySlopeCalc 28 28 // 29 29 // Change the spectrum of the MC showers simulated with Corsika (a power law) 30 30 // to a new one, which can be either, again a power law but with a different 31 // spectral index, or a generalizeed spectra (given as a TF1 object) 31 // spectral index, or a generalizeed spectrum. The new spectrum can be 32 // pass to this class in different ways: 33 // 1. Is the new spectrum will be a power law, just introduce the slope 34 // of this power law. 35 // 2. Is the new spectrum will have a general shape, different options are 36 // available: 37 // a) The new spectrum is pass as a TF1 function 38 // b) The new spectrum is pass as a char* 39 // c) The new spectrum is pass as a "interpreted function", i.e., a 40 // function defined inside a ROOT macro, which will be invoked by the 41 // ROOT Cint itself. This is the case when we use ROOT macros. 42 // d) The new spectrum is pass as a "real function", i.e., a 43 // function defined inside normal c++ file. 32 44 // 33 45 // Method: 34 46 // ------ 35 47 // 36 // -Corsika spectrun: dN/dE = A * E^( -a)48 // -Corsika spectrun: dN/dE = A * E^(a) 37 49 // with a = fCorsikaSlope, and A = N/integral{E*de} from ELowLim to EUppLim 38 50 // … … 43 55 // a weight to each event, given by: 44 56 // 45 // W(E) = B/A * g(E)/E^(-a) 46 // 47 // (The factor B/A is introduced in order both the original and new spectrum 48 // have the same area (i.e. number of showers)) 57 // W(E) = B/A * g(E)/E^(a) 58 // 59 // In the case the new spectrum is simply a power law: dN/dE = B * E^(b), we 60 // have: 61 // 62 // W(E) = B/A * E^(b-a) 63 // 64 // (The factor B/A is used in order both the original and new spectrum have 65 // the same area (i.e. in order they represent the same number of showers)) 49 66 // 50 67 // Note: 51 68 // ------ 52 // -In the calculations, the new spectrum is treated internally as a TF1 53 // object, to give to the user the option of applying a general spectrum. 54 // Is the new spectrum is just a power law (i.e. the user only specify the 55 // slope),it is converted to a TF1 object for consistency. 56 // -With the original corsika spectrum, as it is always a power law, not TF1 57 // object is used to represent the spectrum. 58 // 59 // 69 // -If the the new spectrum is just a power law (i.e. the user only specify 70 // the slope), the needed calculations (such as the integral of the 71 // spectrum) are done analytically. But if the new spectrum is given as a 72 // TF1 object, the calculations is done numerically. 73 // 74 // ToDo: 75 // ----- 76 // -Give to the user also the possibility to specify the integral of the 77 // spectrum as another TF1 object (or C++ function) 78 // 79 // 60 80 // Input Containers: 61 81 // MMcEvt, MMcRunHeader, MMcCorsikaRunHeader … … 85 105 86 106 107 void MMcWeightEnergySpecCalc::Init(const char *name, const char *title) 108 { 109 110 fName = name ? name : "MMcWeightEnergySpecCalc"; 111 fTitle = title ? title : "Task to calculate weights to change the energy spectrum"; 112 113 AddToBranchList("MMcEvt.fEnergy"); 114 115 fAllEvtsTriggered = kFALSE; 116 fTotalNumSimulatedShowers = 0; 117 } 118 119 87 120 // --------------------------------------------------------------------------- 88 121 // 122 // Constructor. The new spectrum will be just a power law. 89 123 // 90 124 MMcWeightEnergySpecCalc::MMcWeightEnergySpecCalc(Float_t slope, … … 92 126 { 93 127 fNewSpecIsPowLaw = kTRUE; 94 95 128 fNewSlope = slope; 96 129 97 fNewSpectrum = new TF1("NewSpectrum","pow(x,[0])"); 98 fNewSpectrum->SetParameter(0,fNewSlope); 99 100 101 fName = name ? name : "MMcWeightEnergySpecCalc"; 102 fTitle = title ? title : "Task to calculate weights to change the energy spectrum"; 103 104 AddToBranchList("MMcEvt.fEnergy"); 105 106 fAllEvtsTriggered = kFALSE; 107 fTotalNumSimulatedShowers = 0; 108 } 109 110 MMcWeightEnergySpecCalc::MMcWeightEnergySpecCalc(TF1* spectrum, 130 fNewSpectrum = NULL; 131 132 Init(name,title); 133 } 134 135 // 136 // Constructor. The new spectrum will have a general shape, given by the user 137 // as a TF1 function. 138 // 139 MMcWeightEnergySpecCalc::MMcWeightEnergySpecCalc(const TF1& spectrum, 111 140 const char *name, const char *title) 112 141 { 113 142 fNewSpecIsPowLaw = kFALSE; 114 115 fNewSpectrum = spectrum; 116 117 fName = name ? name : "MMcWeightEnergySpecCalc"; 118 fTitle = title ? title : "Task to calculate weights to change the energy spectrum"; 119 120 AddToBranchList("MMcEvt.fEnergy"); 121 122 fAllEvtsTriggered = kFALSE; 123 fTotalNumSimulatedShowers = 0; 124 } 125 126 143 fNewSpectrum = (TF1*)spectrum.Clone(); 144 145 Init(name,title); 146 } 147 148 // 149 // As before, but the function which represent the new spectrum is given as 150 // a char* . Starting from it, we build a TF1 function 151 // 152 MMcWeightEnergySpecCalc::MMcWeightEnergySpecCalc(const char* spectrum, 153 const char *name, const char *title) 154 { 155 fNewSpecIsPowLaw = kFALSE; 156 fNewSpectrum = new TF1("NewSpectrum",spectrum); 157 158 Init(name,title); 159 } 160 161 // 162 // As before, but the new spectrum is given as a intrepreted C++ function. 163 // Starting from it we build a TF1 function. 164 // This constructor is called for interpreted functions by CINT, i.e., when 165 // the functions are declared inside a ROOT macro. 166 // 167 // NOTE: you muss do a casting to (void*) of the function that you pass to this 168 // constructor before invoking it in a macro, e.g. 169 // 170 // Double_t myfunction(Double_t *x, Double_t *par) 171 // { 172 // ... 173 // } 174 // 175 // MMcWeightEnergySpecCalc wcalc((void*)myfunction); 176 // 177 // tasklist.AddToList(&wcalc); 178 // 179 // otherwise ROOT will invoke the constructor McWeightEnergySpecCalc( 180 // const char* spectrum, const char *name, const char *title) 181 // 182 MMcWeightEnergySpecCalc::MMcWeightEnergySpecCalc(void* function, 183 const char *name, const char *title) 184 { 185 fNewSpecIsPowLaw = kFALSE; 186 fNewSpectrum = new TF1("NewSpectrum",function,0,1,1); 187 188 Init(name,title); 189 } 190 191 // 192 // As before, but this is the constructor for real functions, i.e. it is called 193 // when invoked with the normal C++ compiler, i.e. not inside a ROOT macro. 194 // 195 MMcWeightEnergySpecCalc::MMcWeightEnergySpecCalc(Double_t (*function)(Double_t*x, Double_t* par), const Int_t npar, const char *name, const char *title) 196 { 197 fNewSpecIsPowLaw = kFALSE; 198 fNewSpectrum = new TF1("NewSpectrum",function,0,1,1); 199 200 Init(name,title); 201 } 202 203 204 205 // ---------------------------------------------------------------------------- 206 // 207 // Destructor. Deletes the cloned fNewSpectrum. 208 // 127 209 MMcWeightEnergySpecCalc::~MMcWeightEnergySpecCalc() 128 210 { 129 delete fNewSpectrum; 130 } 211 if (fNewSpectrum) 212 delete fNewSpectrum; 213 } 214 131 215 132 216 … … 139 223 fMcEvt = (MMcEvt*)pList->FindObject("MMcEvt"); 140 224 if (!fMcEvt) 141 {142 143 144 }145 146 fWeight = (MWeight*)pList->Find Object("MWeight");225 { 226 *fLog << err << dbginf << "MMcEvt not found... exit." << endl; 227 return kFALSE; 228 } 229 230 fWeight = (MWeight*)pList->FindCreateObj("MWeight"); 147 231 if (!fWeight) 148 { 149 fWeight = (MWeight*)pList->FindCreateObj("MWeight"); 150 if (!fWeight) 151 return kFALSE; 152 } 153 232 { 233 *fLog << err << dbginf << "MWeight not found... exit." << endl; 234 return kFALSE; 235 } 236 154 237 return kTRUE; 155 238 } 156 239 157 240 241 158 242 // ---------------------------------------------------------------------------- 159 243 // 160 244 // Executed each time a new root file is loaded 161 // We will need the fCorsikaSlope,and fE{Upp,Low}Lim to calculate the weights245 // We will need fCorsikaSlope and fE{Upp,Low}Lim to calculate the weights 162 246 // 163 247 Bool_t MMcWeightEnergySpecCalc::ReInit(MParList *plist) … … 178 262 179 263 180 fCorsikaSlope = corrunheader->GetSlopeSpec();181 fELowLim = corrunheader->GetELowLim();182 fEUppLim = corrunheader->GetEUppLim();264 fCorsikaSlope = (Double_t)corrunheader->GetSlopeSpec(); 265 fELowLim = (Double_t)corrunheader->GetELowLim(); 266 fEUppLim = (Double_t)corrunheader->GetEUppLim(); 183 267 184 268 fTotalNumSimulatedShowers += runheader->GetNumSimulatedShowers(); … … 195 279 *fLog << inf << "Only triggered events avail: " << (fAllEvtsTriggered?"yes":"no") << endl; 196 280 197 198 199 // 200 // Starting from fCorsikaSlope, and fE{Upp,Low}Lim, calculate the integrals 281 282 283 // 284 // Sanity checks to be sure that we won't divide by zero later on 285 // 286 if(fCorsikaSlope == -1. || fNewSlope == -1.) 287 { 288 *fLog << err << "The Slope of the power law must be different of -1... exit" << endl; 289 return kFALSE; 290 } 291 292 293 // 294 // Starting from fCorsikaSlope and fE{Upp,Low}Lim, calculate the integrals 201 295 // of both, the original Corsika spectrum and the new one. 202 296 // … … 204 298 // For the Corsika simulated spectrum (just a power law), we have: 205 299 // 206 Double_t a = fCorsikaSlope; 207 fCorSpecInt = ( pow(fEUppLim,1+a) - pow(fELowLim,1+a) ) / ( 1+a ); 300 fCorSpecInt = ( pow(fEUppLim,1+fCorsikaSlope) - pow(fELowLim,1+fCorsikaSlope) ) / ( 1+fCorsikaSlope ); 208 301 302 209 303 // 210 304 // For the new spectrum: 211 305 // 212 fNewSpectrum->SetRange(fELowLim, fEUppLim);213 214 306 if (fNewSpecIsPowLaw) // just the integral of a power law 215 307 { 216 Double_t b = fNewSlope; 217 fNewSpecInt = ( pow(fEUppLim,1+b) - pow(fELowLim,1+b) ) / ( 1+b ); 308 fNewSpecInt = ( pow(fEUppLim,1+fNewSlope) - pow(fELowLim,1+fNewSlope) )/ ( 1+fNewSlope ); 218 309 } 219 310 else 220 { // In this case we have to integrate the new spectrum numerically. We 311 { 312 fNewSpectrum->SetRange(fELowLim, fEUppLim); 313 314 // In this case we have to integrate the new spectrum numerically. We 221 315 // could do simply fNewSpectrum->Integral(fELowLim,fEUppLim), but ROOT 222 316 // fails integrating up to fEUppLim for a sharp cutoff spectrum … … 226 320 // fNewSpectrum->Integral(fELowLim,fEUppLim) (although not perfectlly) 227 321 // 228 fNewSpectrum->SetNpx(1 e4);322 fNewSpectrum->SetNpx(1000); 229 323 TGraph gr(fNewSpectrum,"i"); 230 324 Int_t Npx = gr.GetN(); 231 325 Double_t* y = gr.GetY(); 232 326 233 Double_t integral = y[Npx-1];327 const Double_t integral = y[Npx-1]; 234 328 fNewSpecInt = integral; 235 329 } … … 240 334 241 335 336 242 337 // ---------------------------------------------------------------------------- 243 338 // … … 247 342 const Double_t energy = fMcEvt->GetEnergy(); 248 343 249 Double_t weight = fCorSpecInt/fNewSpecInt * fNewSpectrum->Eval(energy) / pow(energy,fCorsikaSlope); 344 const Double_t C = fCorSpecInt / fNewSpecInt; 345 Double_t weight; 346 347 348 if (fNewSpecIsPowLaw) 349 weight = C * pow(energy,fNewSlope-fCorsikaSlope); 350 else 351 weight = C * fNewSpectrum->Eval(energy) / pow(energy,fCorsikaSlope); 250 352 353 251 354 fWeight->SetWeight( weight ); 252 355 … … 271 374 272 375 376 377 378 -
trunk/MagicSoft/Mars/mmontecarlo/MMcWeightEnergySpecCalc.h
r2448 r2474 7 7 8 8 9 10 9 class MParList; 11 10 class MMcEvt; … … 13 12 class TF1; 14 13 14 15 15 class MMcWeightEnergySpecCalc : public MTask 16 16 { 17 private:18 const MMcEvt *fMcEvt;19 MWeight *fWeight;20 17 21 TF1* fNewSpectrum; // Function with the new spectrum18 private: 22 19 23 Bool_t fNewSpecIsPowLaw; // Tells whether the new spectrum is introduce as24 //a TF1 object or not20 const MMcEvt *fMcEvt; 21 MWeight *fWeight; 25 22 26 UInt_t fTotalNumSimulatedShowers; 27 Bool_t fAllEvtsTriggered; 28 Float_t fCorsikaSlope; // Slope of energy spectrum generated with Corsika 29 Float_t fNewSlope; // Slope of the new spectrum (if it is a power law) 30 Float_t fELowLim; 31 Float_t fEUppLim; // Limits of energy range for generation 32 Double_t fCorSpecInt; // Value of the integrals of the Corsika and new 33 Double_t fNewSpecInt; //spectrum respectively, between fElow and fUppLim 23 TF1* fNewSpectrum; // Function with the new spectrum 34 24 25 Bool_t fNewSpecIsPowLaw; // Tells whether the new spectrum is introduced 26 //as a TF1 object or not 27 Double_t fCorsikaSlope; // Slope of energy spectrum generated with Corsika 28 Double_t fNewSlope; // Slope of the new spectrum (if it is a power law) 29 Double_t fELowLim; 30 Double_t fEUppLim; // Limits of energy range for generation 31 Double_t fCorSpecInt; // Value of the integrals of the Corsika and new 32 Double_t fNewSpecInt; //spectrum respectively, between fElow and fUppLim 35 33 34 UInt_t fTotalNumSimulatedShowers; 35 Bool_t fAllEvtsTriggered; 36 36 37 void Init(const char *name, const char *title); 37 38 Bool_t ReInit(MParList *plist); 38 39 … … 41 42 42 43 43 public: 44 public: 45 44 46 MMcWeightEnergySpecCalc(const Float_t slope, 45 47 const char *name=NULL, const char *title=NULL); 46 48 47 MMcWeightEnergySpecCalc(TF1* spectrum, 48 const char *name=NULL, const char *title=NULL); 49 MMcWeightEnergySpecCalc(const TF1& spectrum, 50 const char *name=NULL, const char *title=NULL); 51 52 MMcWeightEnergySpecCalc(const char* spectrum, 53 const char *name=NULL, const char *title=NULL); 54 55 MMcWeightEnergySpecCalc(void *function, 56 const char *name=NULL, const char *title=NULL); 57 58 MMcWeightEnergySpecCalc(Double_t (*function)(Double_t* x, Double_t* par), 59 const Int_t npar, const char *name=NULL, const char *title=NULL); 60 49 61 50 62 ~MMcWeightEnergySpecCalc(); 63 51 64 52 65 ClassDef(MMcWeightEnergySpecCalc, 0) // Task to convert the spectrum of the MC showers simulated with Corsika to a different one, by using weights
Note:
See TracChangeset
for help on using the changeset viewer.